如何为Elm中的嵌套记录制作通用更新功能 [英] How to make a generic update function for a nested record in Elm

查看:63
本文介绍了如何为Elm中的嵌套记录制作通用更新功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在榆树中,我有一个带有嵌套属性的模型,例如:

In Elm I have a model with nested attributes like:

model =
  { name = ""
  , disruptedFields =
    { advertising =
      { name = "Advertising"
      , checked = False
      }
    , travel =
      { name = "Travel"
      , checked = False
      }
    , utilities =
      { name = "Utilities"
      , checked = False
      }
    }
  }

disruptedFields 包含复选框的值列表。当我单击复选框时,我向 UpdateDisruptedField 发送一条更新消息,该消息当前如下所示:

disruptedFields contains a list of values for checkboxes. When I click on the checkbox I send an update message to UpdateDisruptedField, which currently looks like:

UpdateDisruptedField value ->
  let
    fieldCollection = model.disruptedFields
    field = fieldCollection.advertising
  in
    { model | disruptedFields =
      { fieldCollection | advertising =
        { field | checked = (not value) }
      }
    }

我的更新函数是在字段广告 model.disruptedField.advertising $ c>变量。这对我有用,但是我仍然使该函数成为通用函数。

My update function is hard-coded to model.disruptedField.advertising in the field and advertising variables. This is working for me, but I'm stuck making the function generic.

如何将记录传递给UpdateDisruptedField以便使它通用? / strong>

How do I pass the record into UpdateDisruptedField so I can make it generic?

推荐答案

对于输入框很多的Elm应用程序,这是一个常见问题。创建通用更新功能以减少代码重复的方法有两种。

This is a common problem for Elm apps with many input fields. There are two approaches for creating a generic update function to reduce code repetition.


  1. 使用输入的标识符扩展消息以进行更新然后使用 case checkboxType为添加另一个级别的开关,并使用所有嵌套记录处理更新。每次您在模型中添加新字段时,都必须使用一个额外的分支来扩展更新以处理更新。

  1. Extend the message for update with identifier for an input and then add another level of switch with case checkboxType of and handle the update with all the nested Records. Every time you will add a new field in the model, you will have to extend the update with an extra branch for handling the update.

重新组织您的结构使用Dictionary进行建模,并以适当的通用方式处理更新。

Re-structure your model with Dictionaries and handle the update in a proper generic way.

我更喜欢第二种选择,因为更新嵌套记录

I prefer the second option, because updating nested Records is a chore.

请考虑以下示例:

module Main exposing (..)

import Html exposing (div, input, text, label)
import Html.App exposing (beginnerProgram)
import Html.Events exposing (onCheck)
import Html.Attributes exposing (type', checked)
import Dict


(=>) : a -> b -> ( a, b )
(=>) a b =
    ( a, b )


main =
    beginnerProgram { model = model, view = view, update = update }


model =
    { name = ""
    , disruptedFields =
        Dict.fromList
            [ "advertising"
                => { name = "Advertising"
                   , checked = False
                   }
            , "travel"
                => { name = "Travel"
                   , checked = False
                   }
            , "utilities"
                => { name = "Utilities"
                   , checked = False
                   }
            ]
    }


type Msg
    = Check String Bool


view model =
    let
        checkbox ( key, data ) =
            label []
                [ text data.name
                , input
                    [ type' "checkbox"
                    , checked data.checked
                    , onCheck (Check key)
                    ]
                    []
                ]
    in
        div []
            (model.disruptedFields
                |> Dict.toList
                |> List.map checkbox
            )


update msg model =
    case msg of
        Check checkboxId checked ->
            let
                updateRecord =
                    Maybe.map (\checkboxData -> { checkboxData | checked = checked })

                disruptedFieldsUpdated =
                    Dict.update checkboxId
                        updateRecord
                        model.disruptedFields
            in
                { model | disruptedFields = disruptedFieldsUpdated }

请注意,我一直在使用 => ; 运算符使元组看起来更好。

Please note, that I've been using => operator to make Tuples look nicer.

disruptedFields 现在是一个字典,即使用 String 键来标识每个复选框。

disruptedFields is now a Dictionary, that uses String keys to identify every checkbox.

这篇关于如何为Elm中的嵌套记录制作通用更新功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆