假设您要创建一个包含 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;
});
.button {
border: 1px solid black;
cursor: pointer;
margin: 4px;
padding: 4px;
}
.selected {
background-color: #DDDDDD;
}
<div>
<span id='Foo' class='button'>Foo</span>
<span id='Bar' class='button'>Bar</span>
<span id='Tot' class='button'>Tot</span>
</div>
这是有状态的,但不是模块化的,独立的也不是纯粹的。事实上,状态(一个三进制位)甚至不明显是很糟糕的。你不能将它注入(inject)另一个模型,你想要多少次。
到目前为止,此处提供的大多数答案都是有状态的,但不是模块化的。问题是使用该策略,您不能将一个组件放入另一个而父级不了解子级模型。理想情况下,这将被抽象掉——父节点不需要在其自己的模型中提及子节点的模型,也不需要手动将状态从父节点连接到节点。如果我想创建上面应用程序的列表,我不想将每个子节点的状态存储在父节点上。
如何在 Elm 中创建有状态的、模块化的、独立的网络组件?
最佳答案
Elm 可以满足这些要求中的每一个,使您的组件有状态、模块化、独立且纯净。这是 Elm 中使用 StartApp.Simple 的示例(请原谅内联样式):
import StartApp.Simple exposing (start)
import Html exposing (Html, div, span, text)
import Html.Attributes exposing (id, class, style)
import Html.Events exposing (onClick)
type alias Model =
{ elements : List String
, selected : Maybe String
}
init : Model
init =
{ elements = [ "Foo", "Bar", "Tot" ]
, selected = Nothing
}
type Action
= Select String
update : Action -> Model -> Model
update action model =
case action of
Select s ->
{ model | selected = Just s }
view : Signal.Address Action -> Model -> Html
view address model =
let
btn txt =
span
[ id txt
, buttonStyle txt
, onClick address <| Select txt
] [ text txt ]
buttonStyle txt =
style (
[ ("border", "1px solid black")
, ("cursor", "pointer")
, ("margin", "4px")
, ("solid", "4px")
] ++ (styleWhenSelected txt))
styleWhenSelected txt =
case model.selected of
Nothing -> []
Just s ->
if s == txt then
[ ("background-color", "#DDDDDD") ]
else
[]
in
div [] <| List.map btn model.elements
main =
start
{ model = init
, update = update
, view = view
}
您有一个明确定义的静态类型模型、可以针对该模型执行的明确且数量有限的操作,以及一个类型安全的 html 渲染引擎。
看看 Elm Architecture Tutorial获取更多信息。
关于javascript - 如何在 Elm 中创建有状态、模块化、独立的 Web 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34018333/