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
         )