假设您要创建一个包含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组件?
这是同一件事的另一个版本:)
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)