如何在Elm中创建有状态的,模块化的,独立的Web组件?

Mai*_*tor 9 javascript elm

假设您要创建一个包含3个按钮的UI.当您单击其中一个时,其他人将被释放.在JavaScript中,您可以写:

var elements = ["Foo","Bar","Tot"].map(function(name){
  var element = document.getElementById(name);
  element.onclick = function(){
    elements.map(function(element){
      element.className = 'button';
    });
    element.className = 'button selected';
  };
  return element;
});
Run Code Online (Sandbox Code Playgroud)
.button {
  border: 1px solid black;
  cursor: pointer;
  margin: 4px;
  padding: 4px;
}
.selected {
  background-color: #DDDDDD;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <span id='Foo' class='button'>Foo</span>
  <span id='Bar' class='button'>Bar</span>
  <span id='Tot' class='button'>Tot</span>
</div>
  
Run Code Online (Sandbox Code Playgroud)

这是有状态的,但不是模块化的,自包含的,也不是纯粹的.事实上,状态(三元位)甚至不是很明显.你不能将它注入另一个模型,你想要多少次.

到目前为止,这里提供的大多数答案都是有状态的,但不是模块化的.问题是使用该策略,如果父母不知道孩子的模型,就不能将组件放入另一个组件中.理想情况下,这将被抽象掉 - 父母不应该在其自己的模型上提及子节点的模型,也不需要从父节点到节点的手动管道状态.如果我想创建上面的应用程序列表,我不想将每个子节点的状态存储在父节点上.

如何在Elm中创建有状态的,模块化的,独立的Web组件?

dev*_*ave 0

这是同一件事的另一个版本:)

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import StartApp.Simple

type alias Model = Maybe String -- the id of the selected span

type Action = ButtonClick String

update : Action -> Model -> Model
update action model =
  case action of
    ButtonClick id ->
      Just id


view : Signal.Address Action -> Model -> Html
view address model =
  let
    renderButton id' label' =
      let
        selectedClass =
          case model of
            Just modelId -> if modelId == id' then " selected" else ""
            Nothing -> ""
      in
      span [ id id', class ("button" ++ selectedClass), onClick address (ButtonClick id') ] [ text label' ]
  in
  div []
    [ renderButton "foo" "Foo"
    , renderButton "bar" "Bar"
    , renderButton "tot" "Tot"
    ]


main =
  StartApp.Simple.start { model = Nothing, update = update, view = view }
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用嵌套来模块化 Elm 应用程序。因此,您有一个包含更新和查看功能的顶级应用程序组件。然后,您可以在其中嵌套一个“子模块”,方法是在顶级模型记录中为其状态提供一个条目、一个 ChildAction 类型、将 ChildAction 操作发送到子级更新方法的更新函数中的一个条目以及一个信号。 forwardTo 标记来自子级的操作。老实说,目前需要大量重复的样板才能使其发挥作用。我正在寻找一种方法来抽象它,但还没有找到任何优雅的东西。 (2认同)