我只试过了Elm几天,并且遇到了我无法弄清楚的常见情况。如何将操作传递给Elm中的子组件
我有一个包含项目列表的父组件。为了呈现列表,我有一个子组件,父组件调用传递给地址和模型的子视图函数。由于Action类型不同,我认为编译器正在抱怨,但我真的不确定。
父组件:
type alias Model = List ToDoItem.Model
type Action
= Remove Int
update : Action -> Model -> Model
update action model =
case action of
Remove id ->
List.filter (\todo -> todo.id /= id) model
view : Signal.Address Action -> Model -> Html
view address model =
let
buildToDos =
List.map (ToDoItem.view address) model
in
div [] [ buildToDos ]
子组件:
type alias Model =
{ id : Int
, name : String
, description : String
, complete: Bool
}
type alias ID = Int
type Action
= Toggle Bool
update : Action -> Model -> Model
update action model =
case action of
Toggle toggle ->
if toggle == True then
{ model | complete = False }
else
{ model | complete = True }
view : Signal.Address Action -> Model -> Html
view address model =
let
toggleText : Bool -> String
toggleText complete =
case complete of
True -> "Incomplete"
False -> "Complete"
in
div
[ class "wrapper" ]
[ span [] [ text ("[" ++ toString model.id ++ "]") ]
, span [ class "name" ] [ text model.name ]
, div [ class "description" ] [ text model.description ]
, a [ onClick address (Toggle model.complete)] [ text (toggleText model.complete)]
]
编译器错误:
-- TYPE MISMATCH ----------------------------------------------
The type annotation for `view` does not match its definition.
20│ view : Signal.Address Action -> Model -> Html
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The type annotation is saying:
Address Action -> List ToDoItem.Model -> Html
But I am inferring that the definition has this type:
Address ToDoItem.Action -> List ToDoItem.Model -> Html
-- TYPE MISMATCH ----------------------------------------------
The 2nd argument to function `div` is causing a mismatch.
26│ div [] [ buildToDos ]
^^^^^^^^^^^^^^
Function `div` is expecting the 2nd argument to be:
List VirtualDom.Node
But it is:
List (List Html)
如何申报或者子组件的视图功能正常或传入参数从父母正确的孩子的视图功能?
实际上,我实际上并不想将任何操作传递给子组件 - 我只想渲染它。子组件中的动作是针对onClick的。
然后,也许我走了,因为这是我榆树生活的第二天。
谢谢。我已经多次阅读过这个例子,但它似乎并不是我所需要的。我实际上并不需要将信号转发给子组件,因为它不需要知道有关父操作的任何信息。我不能用某种noOp或某种方式调用子视图fn吗? – BoxerBucks
我能够根据这个答案找出问题。我刚刚创建了一个NoOp操作,其中包含一个与子组件操作关联的类似于我刚删除索引的类似操作,因为我不需要它。然后我通过Signal.forwardTo发送。我还不清楚的是信号如何流动。这是否需要与每个父母子女关系发生?行动总是需要被转发? – BoxerBucks
如果ToDoItem具有自己的状态并且改变此状态的操作,那么这种委托在更新和转发视图中是必需的。 这主要是由一个单一的状态产生的。 [此图片](http://staltz.com/img/mvu-unidir-ui-arch.jpg)可以直观地展现榆树发生的事情。 有了Elm架构,人们很少使用信号。 StartApp中有一个很大的'Signal.foldp',很少有'inputs'信号,就是这样。 – pdamoc