2

我正在努力解决一个在使用 KnockoutJS 框架和 MVVM 时不断出现的问题。有时,集合中特定项目的属性发生更改,并且由于该更改,我需要影响同一集合中的所有其他项目。在所有语言和模式中,一个对象不应该“知道”它所在的集合的任何信息,但我发现自己需要经常打破这个规则才能让某些类型的逻辑起作用。

我已经创建了一个人为的示例来说明我正在谈论的内容,以展示我一直在解决这个问题的骇人听闻的方式。我希望有更多经验的人可以参与并告诉我更好的方法来做到这一点。

JSFiddle 人为设计的示例

4

2 回答 2

3

我不知道这是否是“推荐”的方法,但我会就如何解决这个问题提出我的建议。我不是 MVVM 专家(尽管我已经编写了很多 KnockoutJS 应用程序),但我认为一些 OOP 原则将足以在这里提供帮助。

所以首先让我们讨论一下目前的情况......

正如您正确观察到的那样(敲除双关语无意!),您的方法并不理想-Person对象不仅知道它们的兄弟姐妹(即使通过订阅间接地知道),而且还知道它们订阅的父对象-您的Person类型已订阅对父级进行更改。这不仅使您的Person对象在此场景之外无法使用,而且还赋予每个实例过多的责任(违反单一责任原则),并且每个实例都订阅了其他每个实例的更改,这当然是浪费!

那么解决方案是什么?

对我来说,放置这种逻辑的理想位置是在您的父对象(即您的视图模型)上。您的视图模型已经知道它的子对象,那么为什么不把功能放在那里呢?这将使您的Person类型可以在其他地方重用(好吧,所以它有可观察的,所以它现在与 KO 相关联,但这可以通过 Mapping 插件来克服)并减轻它管理其兄弟姐妹的责任。

但这仍然意味着您在父母和孩子之间有紧密的耦合 - 这不是我们在 OOP 中想要的!为了克服这个问题,您可以采用发布/订阅(观察者)模式,并让您的Person类型在发生变化时发布消息,然后您可以让订阅者(例如您查看模型)决定如何响应此事件。您也不一定需要使用淘汰赛的 pub/sub 产品,任何 pub/sub 实现都可以。虽然您也可以利用 KO 提供的功能,所以我会向您指出这些扩展/帮助程序的方向,以使事情变得简单:http ://www.knockmeout.net/2012/05/using-ko-native -pubsub.html

希望我有所帮助:)

于 2012-06-11T20:58:40.277 回答
0

除非我误解了您的情况,否则您可以使用computed自动动态更新的可观察对象。

首先,我认为每个人的“未成年”财产标志只是将他们的年龄与一分钟相比的计算。年龄。例如 19。

其次,您还可以使用computedobservable 为所有用户做一个聚合标志。

最后,我不一定同意这是父子关系。这些只是特定于页面的视图模型的属性。

看看这个在这两种情况下都使用计算的例子。 http://codepen.io/anon/pen/ufKCo

于 2012-10-10T19:46:29.873 回答