建模条件,使用elm-simple-forms的嵌套表单

时间:2016-02-24 08:31:50

标签: elm

我有一个以select开头的表单。根据选择的内容,表格会扩展为公共主位和取决于选择的详细信息部分。

我开始使用单独的详细信息部分进行建模

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
  }

在我开始之前,我会欢迎其他人了解效果良好的经历

3 个答案:

答案 0 :(得分:0)

如果我理解正确,您有书籍,宣传册和卡片的单独模块吗?我不太明白你的模型的目的是什么,但我会像这样构建它:

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值设置为选定的Product。您可以使用以下方式实现选择:

button [ onClick (Details Book) ] [ text "Book" ]

例如选择一本书。稍后你想让它变得动态,第一直觉应该是能够调用所选产品的视图功能。

在其他情况下,您可以定义需要某些字段的视图,每个产品的模型都包含这些字段,然后您可以使用它们在网站上写一些信息。

请注意,上面的代码并不意味着工作,它只是代表这个想法。

答案 1 :(得分:0)

我不熟悉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为您提供了一种在第一种形式(仅选择)和第二种形式(客户详细信息+所选产品类型详细信息)之间进行选择的好方法。

Book.view等给您Html,您可以将其添加到常见案例中:

withCommonFormInputs : Model -> Html Msg -> Html Msg
withCommonFormInputs model productInputs =
    div
      []
      [ input [] [] -- customer
      , input [] [] -- project
      , productInputs -- product (Book, Brochure, Card) subform
      ]

答案 2 :(得分:0)

我最终使用了各个字段的Dict,并在产品更改时更改了字段。试图更明确地模拟每个产品,创造出比我需要的更多的锅炉板。