使用 "The Elm Architecture" 时如何存储子模块的状态
How to store states for sub-modules when using "The Elm Architecture"
我是 Function Programming(FP)
和 Elm 的新手,所以用 FP 方式思考对我来说非常具有挑战性。
我正在开发一个与 Elm Tutorial.
示例非常相似的网络应用程序
为了简单起见,我们假设sub-module
是一个计数器。
它将显示初始值 0 和两个按钮 increase/decrease 该值。
,---. ,---.
| + | 123 | - |
`---' `---'
我的应用程序的简化版本如下所示:
-------------------------------------
type alias Model =
{ contents : List Contents.Content
, routing : Routing
}
type Routing = List | Edit Int
view : Model -> Html
view model =
case model.routing of
Edit id ->
let
maybe = List.head << (List.filter (\c -> c.id == id)) model.contents
in
case maybe of
Just content -> Contents.EditView content
Nothing -> div [] [ text "Error" ]
List -> Contents.listView model.contents
------------------------------------
module Contents where
type alias Content = { someKey : SomeType }
editView : Content -> Html
editView content =
div []
[ Counter.view WHERE_SHOULD_I_GOT_A_Counter.Model_FOR_THIS_CALL
, someOtherViews content
]
listView : List Content -> Html
listView =
listViewImp
---------------------------
module Counter where
type alias Model = Int
view : Model -> Html
view model =
div []
[ button [] [ text "+" ]
, text (toString model)
, button [] [ text "-" ]
]
存在三级视图层次结构:
main view ----> edit view --> counter
|-> list view
每次我从其他视图导航到 edit view
时,计数器值都应该为 0,然后应该只通过单击这两个按钮来修改它,直到我离开该页面。
问题是我应该从哪里得到一个 Counter.Model 传递给 Counter.view?
- 因为计数器是完全独立的,所以我不想让顶层视图知道它的存在,所以它不能从
view
函数发送。
- 如果我在
editView
函数中初始化一个 Counter.Model,每次调用 editView
(可能由其他操作调用)都会将计数器重新初始化为 0
我希望我已经让自己明白了。
感谢阅读所有这些。
感谢大家的评论。
经过Elm Architecture tutorial again, I noticed that its code structure is somehow different from the one used in Elm Tutorial Gitbook之后。对于我的应用程序,最好使用 Elm 架构教程.
中描述的应用程序
有区别:
- Elm Architecture 为所有子模块定义了
Model
Action
update
view
和 init
- 实用模块不计入子模块这里
- 有些
Model
Action
... 可以省略的时候很简单
- Elm Tutorial将某个概念的Models和Actions分开
.elm
文件,并有几个 View 文件(Edit.elm
List.elm
等)导入 Models 和操作数
当某个概念的不同视图仅取决于其 Model
(或其变体,例如 List Model
)时,我们可以采用 Elm 教程中使用的结构。原因是任何使用该概念的高级模块都会将 Model
初始化为 HighLevelModel
的一部分。但是当有一个视图不仅依赖于自身'Model',还需要另一个子模块时,我们就不能使用Elm Tutorial的结构了。在这种情况下,该视图可以被视为一个新模块(事实上,它是一个新模块),因此它应该有自己的 Model
类型并被高层模块导入。
我是 Function Programming(FP)
和 Elm 的新手,所以用 FP 方式思考对我来说非常具有挑战性。
我正在开发一个与 Elm Tutorial.
示例非常相似的网络应用程序为了简单起见,我们假设sub-module
是一个计数器。
它将显示初始值 0 和两个按钮 increase/decrease 该值。
,---. ,---.
| + | 123 | - |
`---' `---'
我的应用程序的简化版本如下所示:
-------------------------------------
type alias Model =
{ contents : List Contents.Content
, routing : Routing
}
type Routing = List | Edit Int
view : Model -> Html
view model =
case model.routing of
Edit id ->
let
maybe = List.head << (List.filter (\c -> c.id == id)) model.contents
in
case maybe of
Just content -> Contents.EditView content
Nothing -> div [] [ text "Error" ]
List -> Contents.listView model.contents
------------------------------------
module Contents where
type alias Content = { someKey : SomeType }
editView : Content -> Html
editView content =
div []
[ Counter.view WHERE_SHOULD_I_GOT_A_Counter.Model_FOR_THIS_CALL
, someOtherViews content
]
listView : List Content -> Html
listView =
listViewImp
---------------------------
module Counter where
type alias Model = Int
view : Model -> Html
view model =
div []
[ button [] [ text "+" ]
, text (toString model)
, button [] [ text "-" ]
]
存在三级视图层次结构:
main view ----> edit view --> counter
|-> list view
每次我从其他视图导航到 edit view
时,计数器值都应该为 0,然后应该只通过单击这两个按钮来修改它,直到我离开该页面。
问题是我应该从哪里得到一个 Counter.Model 传递给 Counter.view?
- 因为计数器是完全独立的,所以我不想让顶层视图知道它的存在,所以它不能从
view
函数发送。 - 如果我在
editView
函数中初始化一个 Counter.Model,每次调用editView
(可能由其他操作调用)都会将计数器重新初始化为 0
我希望我已经让自己明白了。
感谢阅读所有这些。
感谢大家的评论。
经过Elm Architecture tutorial again, I noticed that its code structure is somehow different from the one used in Elm Tutorial Gitbook之后。对于我的应用程序,最好使用 Elm 架构教程.
中描述的应用程序有区别:
- Elm Architecture 为所有子模块定义了
Model
Action
update
view
和init
- 实用模块不计入子模块这里
- 有些
Model
Action
... 可以省略的时候很简单
- Elm Tutorial将某个概念的Models和Actions分开
.elm
文件,并有几个 View 文件(Edit.elm
List.elm
等)导入 Models 和操作数
当某个概念的不同视图仅取决于其 Model
(或其变体,例如 List Model
)时,我们可以采用 Elm 教程中使用的结构。原因是任何使用该概念的高级模块都会将 Model
初始化为 HighLevelModel
的一部分。但是当有一个视图不仅依赖于自身'Model',还需要另一个子模块时,我们就不能使用Elm Tutorial的结构了。在这种情况下,该视图可以被视为一个新模块(事实上,它是一个新模块),因此它应该有自己的 Model
类型并被高层模块导入。