Javascript 带有Knockout.js的MVVM

Javascript 带有Knockout.js的MVVM,javascript,mvvm,knockout.js,Javascript,Mvvm,Knockout.js,我正在尝试实现一个基于MVVM的单页应用程序,目前正在使用framework Knockout.js来处理MVVM的viewmodel/view部分。但我还是很困惑,因为我所看到的每个实现Knockout的示例都涉及到将整个viewmodel保存到数据库中。这些示例是否缺少一个“模型”步骤,其中viewmodel与数据层模型同步,模型执行验证/服务器同步 我希望在单个页面上有多个不同的模板/视图,每个模板/视图具有不同的viewmodel。我发现knockout.js缺少的另一件事是跨不同视图同

我正在尝试实现一个基于MVVM的单页应用程序,目前正在使用framework Knockout.js来处理MVVM的viewmodel/view部分。但我还是很困惑,因为我所看到的每个实现Knockout的示例都涉及到将整个viewmodel保存到数据库中。这些示例是否缺少一个“模型”步骤,其中viewmodel与数据层模型同步,模型执行验证/服务器同步

我希望在单个页面上有多个不同的模板/视图,每个模板/视图具有不同的viewmodel。我发现knockout.js缺少的另一件事是跨不同视图同步单个模型(而不是viewmodel)。我认为每个视图共享一个巨大的viewmodel是没有意义的,所以我认为每个视图都有自己的viewmodel,但每个viewmodel都会与每个视图所需的几个应用程序范围模型的字段同步

我正在处理的页面获取了一个巨大的模型(30多个字段,多个父/子关系层),我认为让我所有的viewmodels与这个模型同步是有意义的。我已经研究了Knockback.js(它结合了knockout.js和backbone.js),但是我最终重新编写了大多数函数,比如fetch、set、save,因为页面从API获取数据(我不能只将整个模型与服务器来回同步),所以我决定不使用它。

我的应用程序的可视示例:

(模型层) M | M

(视图模型/视图层)VM-V | VM-V | VM-V | VM-V


另一个例子

一个示例模型是User={firstName:“first”,lastName:“last”,…}

一个viewmodel只需要名字,另一个viewmodel只需要姓氏
ViewModelA={firstName:app.User.firstName()}
ViewModelB={firstName:app.User.lastName()}


为模型和视图模型更改定义发布/订阅系统是唯一的方法吗?这是一个好的/可维护的体系结构吗?我是否缺少一个基本概念?欢迎所有建议。

这是一个热门的兴趣领域,所以我希望你会得到一些更好的答案,但现在开始

模型

是的,您绝对应该拥有数据的服务器端表示,这就是您的模型。这取决于您的服务器和数据库。对于MVC3,这是您的实体模型。对于Django或Ruby,您将在db设置中定义db模型。这部分取决于您的特定技术。但是agian,是的您应该有一个模型,服务器应该绝对执行数据验证

应用程序(ViewModel)

建议每个视图都有自己的viewmodel。然后,您的页面还可以有一个viewmodel,一个appviewmodel(如果您愿意的话),用于跟踪所有这些视图。如果你走这条路,appviewmodel应该负责在视图之间切换,并实现任何其他应用程序级逻辑(比如hash-bashed导航,另一种流行的单页工具)。这种层次结构非常重要,但并不总是简单的。这将取决于您的应用程序的具体要求。您不限于一个平面视图模型。这不是唯一可能的方法

特别示例:

​var ThingViewModel = function(name, data){
    this.name = ko.observable(name);
    //Additional viewmodel stuffs
};

var AppViewModel = function(initialData){
    //Process initial data    
    this.thing = new ThingViewModel(someName, someData); 

};

我现在正在做一个类似的项目,纯粹是为了学习(不是一个真实世界的应用程序),如果你想看一看真正的exmaples的话。注意,
dev
分支目前远远领先于
master
分支。我确信它包含一些不好的模式(请随意指出,我也在学习),但无论如何,您可能能够从中学到一些东西。

如果我读对了,这里有很多问题,都集中在如何构建带淘汰的MVVM/SPA上。正如你所指出的,有一些事情需要解决。一个是如何在视图模型/视图对之间进行通信

主视图模型 一种方法是使用主视图模型作为@Tyrsius的答案。您的shell可以有一个绑定更多可用数据的viewmodel。主视图模型也可以编排子视图模型。如果您走这条路,那么您必须小心地将外壳绑定到主视图模型,将内部外壳绑定到DOM中的特定HTML元素。如果需要,主视图模型可以促进它们之间的通信

解耦视图/视图模型对 另一个选项是使用viewmodel/视图对,而不使用主viewmodel。每个视图都加载到DOM的一个区域中,并单独绑定。它们作为独立的单元,彼此分离。然后,您可以使用pub/sub在之间进行对话,但如果您所需要的只是一种通过可观察对象同步数据的方法,那么Knockout提供了许多选项。我喜欢的一个是每个viewmodel曲面模型对象。因此,视图有一个viewmodel,它显示(来自模型的)特定于视图的数据。因此,许多视图模型可能以不同的方式显示同一模型。因此,当视图更新viewmodel属性(即模型中的属性)时,它会波及到也使用相同模型的任何其他加载的viewmodel

DataContext 再进一步,您可以创建一个datacontext模块来管理模型中的数据。您向datacontext请求一个模型(例如:客户列表),datacontext检查是否已经对其进行了计算,如果没有,它将通过ajax调用获取它们。无论哪种方式,都是从视图模型和模型中抽象出来的。datacontext获取数据并将模型返回给viewmodel。通过这种方式,您非常解耦,但是您可以通过datacontext共享数据(您的模型)

我可以继续下去。。。但请告诉我这是否回答了你的问题。如果没有,欢迎回答任何其他细节

**免责声明:我正在水疗中心建立一个多景观课程