将道具传递给组件的榆木/功能方式

时间:2016-11-06 02:31:28

标签: data-structures functional-programming elm

我是榆树和功能编程的新手。我正在建立一个费用跟踪应用程序,其模型如下:

initialModel =
    { expenseTransactions =
        [ { date = Date.fromString "2016/10/23"
          , transactions =
              [ { id = 1
                  , amount = 17.54
                  , description = "stuff"
                  , category = 3
                  }
                , { id = 2
                  , amount = 15.0
                  , description = "things"
                  , category = 4
                  }
              ]
          }
      ],
      expenseCategories =
        Dict.fromList [ ( 1, "Rent" ), ( 2, "Groceries" ), ( 3, "Eating out" ) ]
    }

在我看来,我使用renderExpensesTable函数,后者又调用renderExpensesForOneDay函数,该函数又调用renderExpensesRow函数。

我想要做的是继续将交易category存储为数字,然后通过在其他语言中执行类似expenseCategories[transaction.category]的操作来从视图中引用其名称。 (我得到的是,如果我只是将类别存储为类似"Groceries"的字符串,这个问题就没有实际意义了,但我想将category作为数字存储在模型中然后单独引用它的原因是用户将能够编辑类别名称,并且我不希望每次发生时都必须更新模型中的每个事务,如果我将category存储为,我将不得不这样做一个字符串。)

我已经意识到我必须将expenseCategories方法从view方法向下传递到每个级别(renderExpensesTablerenderExpensesForOneDay等)。

renderExpenseRow : ExpenseTransaction -> List String -> Html msg
renderExpenseRow transaction categories =
    -- ... row stuff ...

renderExpensesForOneDay : ExpensesForOneDay -> List String -> Html msg
renderExpensesForOneDay day categories =
    let
        dayTransactions =
            List.map2 renderExpenseRow day.transactions categories
    in
        -- ... yada yada ...
        dayTransactions

renderExpensesTable : List ExpensesForOneDay -> List String -> Html msg
renderExpensesTable days categories =
    let
        renderedDays =
            List.map2 renderExpensesForOneDay days (Dict.values categories)
    in
        div [ class "expenses-table" ] renderedDays

这不起作用,我认为这是因为我可能不应该尝试使用List.map2。在尝试传递类别之前,我在map成功了,这是我尝试将它们与其他东西一起传递(比如React中的道具)。

什么是理想的"榆树方式"做这种事情?如果我们无法直接访问模型,并且我们没有React风格的道具,我们应该如何处理我们想要引用的模型的两个不同位的情况,例如{{1} }和expenseTransactions

1 个答案:

答案 0 :(得分:1)

为什么不在selfsame模型中存储单独的类别结构?

类似的东西:

type Model = 
  Model { expenseTransactions: tl
        , expenseCategories: Dict.fromList [ ( 1, "Rent" ), ( 2, "Groceries" ), ( 3, "Eating out" ) ] }

最后所有的视图功能都将采用这个大型模型:

viewWhatever : Model -> Html Msg
viewWhatever = ...
  

我仍然无法通过该模型。每个渲染函数通过List.map连接到下一个渲染函数,因为它只将列表作为参数,如何通过模型传递

您可以修改这些渲染函数,将模型作为第一个参数。例如:

renderExpensesForOneDay : Model -> ExpensesForOneDay -> List String -> Html msg
...

renderExpensesTable : Model -> List ExpensesForOneDay -> List String -> Html msg
...
      List.map2 (renderExpensesForOneDay model) days (Dict.values categories)

请注意上面的句子如何将curried函数(renderExpensesForOneDay model)传递给List.map2。