Functional programming 如何在elm中的不同模型之间共享一些值 更新日期5-14-2016
很抱歉,因为我的英语不好,我没能把我的问题解释清楚。这一次,我抽象了这个问题,并用一个反例演示了它 有两个子模块(Functional programming 如何在elm中的不同模型之间共享一些值 更新日期5-14-2016,functional-programming,frontend,elm,Functional Programming,Frontend,Elm,很抱歉,因为我的英语不好,我没能把我的问题解释清楚。这一次,我抽象了这个问题,并用一个反例演示了它 有两个子模块(CounterPair和counterprilet),每个子模块使用Counter显示num共享模型的field,并显示其他内容(本例中的其他计数器)。我用红色突出显示了计数器显示SharedModel的num CounterPair和counterpree的红色计数器应该同步,因为它们代表相同的共享模型。此外,当任何红色计数器更新时,模型的共享字段也需要更新。下面显示的代码只显示了
CounterPair
和counterprilet
),每个子模块使用Counter
显示num
共享模型的field,并显示其他内容(本例中的其他计数器
)。我用红色突出显示了计数器
显示SharedModel
的num
CounterPair
和counterpree
的红色计数器
应该同步,因为它们代表相同的共享模型
。此外,当任何红色计数器更新时,模型的共享字段也需要更新。下面显示的代码只显示了我想要的内容,但缺少更新链。我应该如何实现更新链
您可以在上尝试此代码
导入Html(div、按钮、文本)
将Html.App作为应用程序导入(初学者程序)
导入Html.Events(onClick)
导入Html.Attributes(样式)
主要=
初学者程序{model=init,view=view,update=update}
-------------------------------------
类型别名SharedModel=
{num:Int
,foo:String
}
sharedInit=
SharedModel 0“Foo”
--------------------------------------
类型别名模型=
{共享:SharedModel
一对
,三重态:反三重态
}
初始=
让
共享的
在里面
模型共享(pairInit共享)(三元组共享)
视图模型=
分区[]
[应用程序地图对(pairView模型地图对)
,App.map三元组(tripletView model.Triplet)
]
输入味精
=对配对sg
|三重态三重态
更新msg模型=
味精案例
配对子->
让
pair=pairUpdate子模型.pair
在里面
{model | pair=pair}
三重态子->
让
三元组=三元组更新子模型。三元组
在里面
{模型|三重态=三重态}
----------------------------------------
类型别名计数器三元组=
{localFst:CounterModel
,localSnd:CounterModel
,全球:反模式
}
三联体IT共享=
计数器三元组(计数器初始化0)(计数器初始化0)(计数器初始化共享.num)
三视图模型=
div[样式[(“背景色”、“浅灰色”),(“页边距底部”、“1rem”)]]
[App.map TriLocalSnd(反视图“绿色”模型.localFst)
,App.map TriLocalSnd(反视图“绿色”model.localSnd)
,App.map TriGlobal(反视图“红色”模型.全局)
]
类型TripletMsg
=TrifocalFST计数器msg
|三声道计数器
|三叶反味精
三重更新msg模型=
味精案例
三声道ST子->
让
localFst=计数器更新子模型。localFst
在里面
{model | localFst=localFst}
三声道亚声道->
让
localSnd=计数器更新子模型。localSnd
在里面
{model | localSnd=localSnd}
三叶亚->
让
全局=计数器更新子模型.global
在里面
{model | global=global}
----------------------------------------------
类型别名对空=
{局部:反模型
,全球:反模式
}
派里尼特共享=
CounterPair(counterInit 0)(counterInit shared.num)
pairView模型=
div[样式[(“背景色”、“浅灰色”),(“页边距底部”、“1rem”)]]
[App.map PairLocal(对视图“绿色”模型.本地)
,App.map PairGlobal(反视图“红色”模型.全局)
]
类型PairMsg
=双本地计数器msg
|对叶计数器
pairUpdate msg模型=
味精案例
成对局部亚->
让
local=反更新子模型.local
在里面
{model | local=local}
成对叶次->
让
全局=计数器更新子模型.global
在里面
{model | global=global}
---------------------------------------
类型别名计数器模型=
{num:Int
,btnClicks:Int
}
计数器初始化数=
反模型编号0
对视图颜色模型=
div[样式[(“显示”、“内联块”),(“右边距”、“1rem”)]]
[按钮[点击减量][文本“-”]
,div[style[(“color”,color)][text(toString model.num)]
,按钮[onClick Increment][text“+”]
,div[]文本(“btn点击:”++(toString模型.btnClicks))]
]
类型CounterMsg=增量|减量
反更新msg模型=
味精案例
增量->
{model | num=model.num+1,btnClicks=model.btnClicks+1}
减量->
{model | num=model.num-1,btnClicks=model.btnClicks+1}
原始问题
我使用的是Elm架构,视图层次结构如下
,--------------------------------------------------------------------.
| View |
| ,------------------. ,------------------------------------------. |
| | SubView1 | | SubView2 | |
| | ,--------------. | | ,---------------. ,--------------------. | |
| | | Label(title) | | | | Label(title) | | Label(description) | | |
| | `--------------' | | `---------------' `--------------------' | |
| `------------------' `------------------------------------------' |
`--------------------------------------------------------------------'
标签
是一个定制的
标签,双击该标签可变成
字段。所以它是可编辑的
型号
s如下所示。问题是我想在编辑子标签的值时更新ViewModel
的内容。当我更新子视图1的标题标签时,子视图2的标题标签也应该更新,因为它们应该“共享”相同的内容
但是LabelModel
的value
在某种程度上是独立的,因此我需要将value
的更改一直转移到ViewModel
。我不认为这是一种实现我想要的东西的实用方法,因为视图层次结构可能会变得更加复杂。此外,几乎所有的模型
都有特定的东西(Foo
,Bar
,BarBar
,等等,用于存储状态),因此它们需要初始化。因此,使ViewModel
整洁,例如type alias ViewModel=Content
,是不切实际的,因为我不知道在哪里可以获得subviewmodel的Bar
和BarBar
<
type alias ViewModel =
{ content : Content
, subView1 : SubViewModel1
, subView2 : SubViewModel2
}
type alias SubViewModel1 =
{ content : Content
, label : Label
, bar : Bar
}
type alias SubViewModel2 =
{ content : Content
, titleLabel : Label
, descLabel : Label
, barbar : BarBar
}
type alias Content =
{ title: String
, description : String
}
type alias LabelModle =
{ value : String
, state : Foo
}
module View
import SubView1
import SubView2
type alias ViewModel =
{ content : Content
, subView1 : SubView1.Model
, subView2 : SubView2.Model
, label : String -- New!
}
type Msg
= SubView1Msg SubView1.Msg
| SubView2Msg SubView2.Msg
| ...
update action model =
case action of
...
(SubView1.UpdateLabel str) as action' ->
let
(subView1', fx) =
SubView1.update action' model.subView1
in
( { model
| subView1 = subView1'
, label = str
}
, Cmd.map SubView1Action fx
)