Cmd.map是将Elm SPA分成模块的正确方法吗?

问题描述

我正在Elm中构建一个单页应用程序,难以决定如何将我的代码拆分为文件

我最终使用每页1个模块对其进行拆分,并使用Main.elmHtmlCmdCmd.map转换为每一页发出的Html.mapCmd.map

我的问题是Cmd.map和Html.map says that的文档:

这在结构良好的Elm代码中很少有用,因此在达到此目的之前一定要阅读指南中有关结构的部分!

我检查了仅有的两个大型应用程序:

  1. elm-spa-example使用Cmd.map(https://github.com/rtfeldman/elm-spa-example/blob/cb32acd73c3d346d0064e7923049867d8ce67193/src/Main.elm#L279
  2. 我无法弄清楚https://github.com/elm/elm-lang.org 解决这个问题。

此外,对this stackoverflow question的两个答案都建议您使用with open('example.txt','r') as file_handle: example_file_content = file_handle.read().split("\n") new_company_line = -10 for index,line in enumerate(example_file_content): if index == new_company_line+2: print("description:",line) if "is one of the top" in line: print("company name =",line.split(" ")[0]) new_company_line = index if line.startswith("Founding Year"): print('founding year =',line.split(":")[1].strip()) if line.startswith("Headquarters"): print("headquarters = ",line.split(":")[1].strip()) if line.startswith("Website"): print("website = ",line.split(":")[1].strip()) if line.startswith("Founders"): print("founders =",line.split(":")[1].strip()) ,不要再三思。

Cmd.map是在模块中拆分单个页面应用程序的“正确”方法吗?

解决方法

我认为有时候您只需要为自己做正确的事即可。对于我编写的具有3个“页面”的应用程序-初始化,编辑和报告,我使用了Cmd.map / Sub.map / Html.map方法。

我想将这些页面中的每个页面都设为自己的模块,因为它们相对复杂,每个页面都有相当数量的消息,这些消息仅与每个页面相关,并且更容易根据自己的上下文来推理每个页面。 / p>

不利之处在于,编译器不会阻止您收到给定页面的错误消息,从而导致运行时错误(例如,如果应用程序在{{1中时收到Editing.Save }}页面上的正确行为是什么?对于我的特定实现,我只是将其登录到控制台并继续操作-这对我来说已经足够了(无论如何它从未发生过);我考虑过的其他选项包括显示讨厌的内容错误页面,表明发生了一些可怕的事情-如果您愿意,则显示BSOD;或者只需重置/重新初始化整个应用程序即可。

,

一种替代方法是使用{strong>效果模式,如this discourse post中所述。

此方法的核心是:

此应用程序中使用的扩展效果模式包括定义一个Effect自定义类型,该类型可以表示init和update函数想要产生的所有效果。

主要好处:

  1. 所有效果都在单个Effect模块中定义,该模块充当整个应用程序的内部API,可以保证列出所有可能的效果。
  2. 可以检查和测试效果,与Cmd值不同。这样就可以测试所有应用程序效果,包括模拟的HTTP请求。
  3. 效果可以表示对顶级模型数据的修改,例如登录3时的会话3或子页面更新功能希望更改URL时的当前页面。
  4. 所有更新功能均保持简洁明了的Msg-> Model->(Model,Effect Msg)2签名。
  5. 由于效果值包含所需的最少信息,因此仅在效果执行3功能中才需要某些参数(例如Browser.Navigation.key),这使开发人员无需将其传递给整个应用程序。
  6. 单个NoOp或忽略的字符串25可以用于整个应用程序。