在上一个问题中,我询问了如何以惯用方式为 F# 应用程序实现观察者模式。我的应用程序现在使用推荐的MailboxProcessor,并且我创建了一些辅助函数来创建子 MailboxProcessor 等。但是,当涉及到 GUI 绑定的特定案例场景时,我处于精神障碍。
可以说我有一个这样的模型:
type Document = {
Contents : seq<DocumentObject>
}
GUI(WPF、XAML)需要像这样的绑定:
interface IMainWindowViewModel
{
IEnumerable<Control> ContentViews { get; }
}
每ViewModel
一个Control
都需要一个DocumentObject
(它的底层模型)和一种知道它是否已经改变的方法。我将其作为子提供MailboxProcessor<DocumentObject>
,以便可以正确传播更改,我有信心这种模式有效。本质上,它映射服务输出并包装修改请求(下面的外部接口示例):
let subSvc = generateSubSvc svc (fun doc -> doc.Contents[0]) (fun f -> fun oldDoc -> { oldDoc with Contents[0] = f Contents[0] })
let viewModel = new SomeDocObjViewModel(docObjSvc)
new DocObjView(viewModel)
现在,想象一个修改命令现在删除了一个DocumentObject
from MyDocument
。顶层现在呼应了使用它的MailboxProcessor
更改。这就是我的问题开始的地方。IMainWindowViewModel
IEvent<MyDocument>
我IMainWindowViewModel
真的不知道 哪个DocumentObject
被删除了。只是有一个新的Document
,它必须处理它。它可能有办法弄清楚,但它永远不会真正直接知道。这可能迫使我不得不重新创建所有Control
' 以确保所有DocumentObject
' 的安全(效率低下)。subSvc
为简洁起见,我也没有在这里提到其他问题(例如悬空的)。
通常情况下,这些动态变化会被处理类似 anObservableCollection<DocumentObject>
然后映射到ObservableCollection<Control>
. 这带有共享可变状态的所有警告,并且有点“hackish”;但是,它确实可以完成这项工作。
理想情况下,我想要一个“纯”模型,没有 and 的陷阱,PropertyChanged
F ObservableCollections
# 中什么样的模式可以满足这种需求?在惯用语和现实主义之间划清界限在哪里合适?