如何使用" Elm Architecture"存储子模块的状态。

时间:2016-05-10 07:11:53

标签: web functional-programming reactive-programming elm

我是Function Programming(FP)Elm的新手,所以用FP方式思考对我来说非常具有挑战性。

我正在开发一个与Elm Tutorial示例非常相似的网络应用。

为简单起见,我们假设sub-module是一个计数器。 它将显示初始值0和两个按钮以增加/减少该值。

,---.     ,---.
| + | 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?

  1. 因为计数器是完全独立的,所以我不希望顶层视图知道它的存在,所以它不能从view函数发送。
  2. 如果我在editView函数中初始化Counter.Model,则每次调用editView(可能由其他操作调用)都会将计数器重新初始化为0
  3. 我希望自己能够理解。

    感谢您阅读所有这些内容。

1 个答案:

答案 0 :(得分:1)

感谢各位评论。

再次浏览Elm Architecture tutorial后,我注意到它的代码结构与Elm Tutorial Gitbook中使用的代码结构有所不同。对于我的应用程序,最好使用 Elm Architecture教程中描述的那个。

有区别:

  • Elm Architecture 为所有子模块定义Model Action update viewinit
    • 实用程序模块不算作子模块
    • 部分Model Action ...在非常简单时可省略
  • Elm Tutorial 将特定概念的模型操作放入单独的.elm文件中,并有一些查看正在导入模型操作
  • 文件(Edit.elm List.elm等)

当某个概念的不同视图仅取决于其Model(或其变体,例如List Model)时,我们可以采用 Elm Tutorial 中使用的结构。原因是任何使用该概念的高级模块都会将Model初始化为HighLevelModel的一部分。但是当有一种观点不仅取决于它自己的“模型”而且还需要另一个子模块时,我们就不能使用 Elm Tutorial 的结构。在这种情况下,该视图可以被视为一个新模块(事实上,它是一个新模块),因此它应该有自己的Model类型,并由高级模块导入。