建模条件,带有 elm-simple-forms 的嵌套形式
Modeling condition, nested forms with elm-simple-forms
我有一个以 select 开头的表格。根据 selected 的内容,表格会扩展到一个公共的主要部分和一个取决于 selection 的细节部分。
我开始使用单独的细节部分建模
type ProductDetails
= Book Book.Model
| Brochure Brochure.Model
| Card Card.Model
type alias Model =
{ form : Form CustomError Estimate
, details : ProductDetails -- a Form CustomerError CardModel / BookModel / ....
, msg : String
}
但这变得非常复杂,例如view
.
备选方案似乎是有条件地将详细信息添加到主表单模型中 - 例如
type alias Estimate =
{ customer : String
, project : String
, product : String
, details : ProductDetails
}
在我开始之前,我欢迎其他人的成功经验
如果我没理解错的话,你们有独立的书籍、小册子和卡片模块吗?我不太明白你的模型的目的是什么,但我会这样构造它:
import Book
import Brochure
import Card
type Products
= Book
| Brochure
| Card
type Msg
= Details Products
type alias Model =
{ selectedProduct : Product
}
update : Msg -> Model -> Model
update msg model =
case msg of
Details prd ->
Model prd
view : Model -> Html
view model =
model.selectedProduct.view
所以你可以看到,现在你定义了所有可用的产品,然后你说 Msg 可以是 Details,它会显示详细信息,它的功能是将 Model 中的 selectedProduct 值设置为 selected 产品。您可以使用 selecting 实现:
button [ onClick (Details Book) ] [ text "Book" ]
例如 select 一本书。稍后您想使其动态化,第一直觉应该是能够调用 selected Product.
的视图函数
在其他情况下,您可以定义需要一些字段的视图,每个产品的模型都将包含这些字段,然后您可以使用它们在网站上编写一些信息。
请注意,上面的代码并不是为了工作,它只是为了表达这个想法。
我不熟悉 elm-simple-forms
,但这似乎很好地代表了您的表单:
type ProductType
= TBook
| TBrochure
| TCard
type Product
= Book Book.Model
| Brochure Brochure.Model
| Card Card.Model
type alias Model =
{ product : Maybe Product
, customer : String
, project : String
}
type Msg
= SelectProductType ProductType
init : Model
init =
{ product = Nothing
, customer = ""
, project = ""
}
update : Msg -> Model -> Model
update msg model =
case msg of
SelectProductType product ->
{model | product =
case product of
TBook -> Book Book.init
TBrochure -> Brochure Brochure.init
TCard -> Card Card.init
}
view : Model -> Html Msg
view model =
case model.product of
Nothing ->
myProductTypeSelect
Just product ->
withCommonFormInputs
<| case product of
Book submodel -> Book.view submodel
Brochure submodel -> Brochure.view submodel
Card submodel -> Card.view submodel
Maybe
为您提供了一种在第一种形式(仅 select)和第二种形式(客户详细信息 + selected 产品类型详细信息)之间进行选择的好方法。
Book.view
等给你 Html
你可以添加到常见的情况:
withCommonFormInputs : Model -> Html Msg -> Html Msg
withCommonFormInputs model productInputs =
div
[]
[ input [] [] -- customer
, input [] [] -- project
, productInputs -- product (Book, Brochure, Card) subform
]
我最终使用了各个字段的Dict,并在产品更改时更改了字段。尝试更明确地为每个产品建模会创建比我需要的更多样板。
我有一个以 select 开头的表格。根据 selected 的内容,表格会扩展到一个公共的主要部分和一个取决于 selection 的细节部分。
我开始使用单独的细节部分建模
type ProductDetails
= Book Book.Model
| Brochure Brochure.Model
| Card Card.Model
type alias Model =
{ form : Form CustomError Estimate
, details : ProductDetails -- a Form CustomerError CardModel / BookModel / ....
, msg : String
}
但这变得非常复杂,例如view
.
备选方案似乎是有条件地将详细信息添加到主表单模型中 - 例如
type alias Estimate =
{ customer : String
, project : String
, product : String
, details : ProductDetails
}
在我开始之前,我欢迎其他人的成功经验
如果我没理解错的话,你们有独立的书籍、小册子和卡片模块吗?我不太明白你的模型的目的是什么,但我会这样构造它:
import Book
import Brochure
import Card
type Products
= Book
| Brochure
| Card
type Msg
= Details Products
type alias Model =
{ selectedProduct : Product
}
update : Msg -> Model -> Model
update msg model =
case msg of
Details prd ->
Model prd
view : Model -> Html
view model =
model.selectedProduct.view
所以你可以看到,现在你定义了所有可用的产品,然后你说 Msg 可以是 Details,它会显示详细信息,它的功能是将 Model 中的 selectedProduct 值设置为 selected 产品。您可以使用 selecting 实现:
button [ onClick (Details Book) ] [ text "Book" ]
例如 select 一本书。稍后您想使其动态化,第一直觉应该是能够调用 selected Product.
的视图函数在其他情况下,您可以定义需要一些字段的视图,每个产品的模型都将包含这些字段,然后您可以使用它们在网站上编写一些信息。
请注意,上面的代码并不是为了工作,它只是为了表达这个想法。
我不熟悉 elm-simple-forms
,但这似乎很好地代表了您的表单:
type ProductType
= TBook
| TBrochure
| TCard
type Product
= Book Book.Model
| Brochure Brochure.Model
| Card Card.Model
type alias Model =
{ product : Maybe Product
, customer : String
, project : String
}
type Msg
= SelectProductType ProductType
init : Model
init =
{ product = Nothing
, customer = ""
, project = ""
}
update : Msg -> Model -> Model
update msg model =
case msg of
SelectProductType product ->
{model | product =
case product of
TBook -> Book Book.init
TBrochure -> Brochure Brochure.init
TCard -> Card Card.init
}
view : Model -> Html Msg
view model =
case model.product of
Nothing ->
myProductTypeSelect
Just product ->
withCommonFormInputs
<| case product of
Book submodel -> Book.view submodel
Brochure submodel -> Brochure.view submodel
Card submodel -> Card.view submodel
Maybe
为您提供了一种在第一种形式(仅 select)和第二种形式(客户详细信息 + selected 产品类型详细信息)之间进行选择的好方法。
Book.view
等给你 Html
你可以添加到常见的情况:
withCommonFormInputs : Model -> Html Msg -> Html Msg
withCommonFormInputs model productInputs =
div
[]
[ input [] [] -- customer
, input [] [] -- project
, productInputs -- product (Book, Brochure, Card) subform
]
我最终使用了各个字段的Dict,并在产品更改时更改了字段。尝试更明确地为每个产品建模会创建比我需要的更多样板。