我正在创建一个可以包含类型A或类型B的项目的待办事项列表。所以我创建了Item
或A
类型B
。该模型包含ItemModel
列表和一个整数,我们用它来为每个待办事项分配一个id。
module Feed where
import A
import B
-- MODEL
type Item = A | B
type ItemModel = A.Model | B.Model
type alias Id = Int
type alias Model =
{ todo : List (Id, ItemModel)
, nextCount : Id}
init : Model
init = Model [] 0
以下功能用于通过使用ItemModel
进行查找来更新模型中的Id
。
updateItem : (ItemModel -> ItemModel) -> Id -> Model -> Model
updateItem f id model =
let test (id', x) = (id', if id == id' then f x else x)
in Model (List.map test model.todo) model.nextCount
麻烦从这里开始。我不知道如何使用已调用操作的Item的更新功能。 Item.update
不起作用,因为它不存在。
-- UPDATE
type Action = SubAction Id Item.Action
update : Action -> Model -> Model
update action model =
case action of
SubAction id action ->
updateItem (Item.update action) id model
我也无法显示我的列表,我知道Item.view
不起作用,但这是为了说明我的想法。如果f.e.代码有效。我使用A.view
并拥有todo : List (Id, A.Model)
,但我希望它适用于A
和B
。我该如何解决这个问题?
-- VIEW
view : Signal.Address Action -> Model -> Html
view address model =
let view' (id, x) = Item.view (Signal.forwardTo address <| SubAction id) x
lstTodo = List.map view' model.todo
in Html.div [] lstTodo
答案 0 :(得分:3)
首先,而不是List (Id, ItemModel)
更好地使用Dict
。
然后只是模式匹配(代码未经测试):
type Item = ItemA A.Model | ItemB B.Model
type Action = SubActionA Id A.Action | SubActionB Id B.Action | ...
updateA : A.Action -> Item -> Item
updateA action model = case model of
ItemA model -> ... -- we have an A item here, do something
Nothing -> ... -- there's a B item here, app logic must be wrong somewhere
updateB : B.Action -> Item -> Item
updateB action model = case model of
ItemB model -> ... -- we have a B item here, do something
Nothing -> ... -- there's an A item here, app logic must be wrong somewhere
update : Action -> Model -> Model
update action model =
case action of
SubActionA id action -> { model | todo = Dict.update id (Maybe.map (updateA action)) model.todo }
SubActionB id action -> { model | todo = Dict.update id (Maybe.map (updateB action)) model.todo }
这里有{p> updateA/B action
- 因此类型为ItemModel -> ItemModel
。
另请注意,Maybe.map
会将函数a -> b
映射到Maybe a -> Maybe b
- 正是Dict.update
所期望的!
同样在视图中:
case model of
ItemA model -> A.view model
ItemB model -> B.view model
如需进一步参考 - 请阅读this,尤其是有关已标记联盟的部分。