将标志转换为模型的 Elm 方法

The Elm way of transforming flags to model

我的应用程序中有以下类型:

type Page
    = Welcome
    | Cards


type alias Flags =
    { recipientName : String
    , products : List Product
    }


type alias Product =
    { id : Int
    , name : String
    , price : Float
    , liked : Maybe Bool
    }


type alias Model =
    { recipientName : String
    , currentPage : Page
    , products : List Product
    }

我正在传递一系列产品作为标志。这是我的 init 的样子:

init : Flags -> ( Model, Cmd Msg )
init flags =
    let
        { recipientName, products } =
            flags
    in
        Model recipientName Welcome products
            |> withNoCmd

我面临的挑战是这个数组中的产品只有 idnameprice 属性。因此,根据 Flags 定义,每次我用新属性(例如 liked)扩展 Product 时,作为标志传递的产品数组也需要具有该属性。现在,我只是将它们渲染为空,但这感觉不对,所以我想知道接收标志并将其转换为模型的 Elm 方式是什么?谢谢!

听起来您的 Product 已被定义为您应用的输入(或环境):

type alias Product =
    { id : Int
    , name : String
    , price : Float
    }

并且您正在使用将收件人与产品相关联的信息来扩充它。我建议将其拆分为自己的类型,可以随着您的应用程序的增长而增长,例如:

type alias Opinion =
    { liked : Maybe Bool
    , review : String
    , preferredColor : Color
    }

然后你可以在你的 Model:

中将它们联系在一起
type alias Model =
    { recipientName : String
    , currentPage : Page
    , products : List (Product, Opinion)
    }

或者,根据应用程序的工作方式,您可能最终想要通过 product.id:

查找收件人的意见
    ...
    , products : List Product
    , opinions : Dict Int Opinion

要点是,如果您保持原始 Product 不变,您可以构建一个适用于 Product 的小型函数库,用于库存(不涉及收件人)和客户。也许您可以将 Opinion 类型重新用于客户指标。

如果这两种类型可能会发展,将它们分开可以帮助确保您不会以混乱和吸引错误的相互依赖关系告终。