在敲出.js中将视图模型拆分为多个视图模型 [英] Split viewmodel into multiple viewmodels in knockout.js
问题描述
在Knockout.js中,当您的ViewModel变得很大时,可以采用多种方法将其拆分为多个ViewModel,最好还是使用多个较小的ViewModel而不是一个较大的ViewModel.我正在使用以下方法,不确定是否还有其他更好的方法可以做到这一点.注意:我正在使用require.js定义我的ViewModel,但是为了简单起见,我在下面的示例中未包含该代码.在下面的示例中,假设我在一个屏幕上可以编辑学生所注册的课程.最初,我在StudentViewModel中具有所有与课程相关的功能(例如添加/编辑/删除课程).但是我决定将它们移到CourseViewModel,然后在StudentViewModel中引用CourseViewModel.请注意,在创建CourseViewModel时,我传递了对student.courses可观察数组的引用.这是为视图使用小型ViewModel的好方法,还是有更好的方法呢?
In Knockout.js, when your ViewModel gets quite big, there are different ways to split into multiple ViewModels and it is always a good idea to have a number of smaller ViewModels instead of having one big one. I am using the following approach and not sure if there is any other better way of doing this. Note I am using require.js to define my ViewModels but I am not including that code in the example below for the sake of simplicity. In the following example let's say that I am working on a screen where you can edit courses that a student is enrolled in. Initially I had all courses related functionality (such as add/edit/remove courses) in the StudentViewModel. But I decided to move them to CourseViewModel and then have a reference to the CourseViewModel in StudentViewModel. Please note when creating CourseViewModel, I am passing a reference to student.courses observable array. Is this a good way to have small viewmodels for a View or is there any better way of doing this?
function Course(data) {
data = data || {};
this.id = ko.observable(data.id);
this.name = ko.observable(data.name);
}
function Student(data) {
data = data || {};
this.id = ko.observable(data.id);
this.firstName = ko.observable(data.firstName);
this.courses = ko.observableArray($.map(data.courses, function (item) { return new Course(item); }));
}
function CourseViewModel(studentid, courses) {
var self = this;
// please note below is a reference to courses observable function
self.courses = courses;
this.addCourse = this.addCourse.bind(this);
this.editCourse = this.editCourse.bind(this);
this.removeCourse = this.removeCourse.bind(this);
}
ko.utils.extend(CourseViewModel.prototype, {
addCourse: function(course) {
var self = this;
self.courses.push(course);
},
editCourse: function(course) {
var self = this;
// find the course and update it
},
removeCourse: function(course) {
var self = this;
self.courses.remove(course);
}
});
// main ViewModel which will be used for binding
function StudentViewModel(id) {
var self = this;
self.id = ko.observable(id);
self.student = ko.observable();
self.courseViewModel = ko.observable();
// retrieve student object from server
(function() {
var data = dataService.getStudent(id);
self.student(new Student(data));
// please note below I am passing a reference to courses observable function
self.courseViewModel(new CourseViewModel(id, student.courses));
)();
}
// binding
ko.applyBindings(new StudentViewModel(5));
推荐答案
我的方法是维护主视图模型(大型胖视图模型)并在其中定义子视图模型.
My way of doing it is maintain master viewmodel (big fat viewmodel) and define sub viewmodels inside it..
例如
var MasterVM = {
subVM1 : SubViewModel1(),
subVM2: SubViewModel2()
};
您可以在需要的任何时间和地点将绑定与主视图模型一起使用,并使用子视图模型实例.
You can apply bindings with master viewmodel and use sub viewmodel instances whenever and wherever you need.
我尝试了不同的技术,但是它们显然失败了.这是我仅从KnockoutJS移至DurandalJS的唯一原因.模块化编程可以很好地工作,而不必担心多个视图模型.
I tried different techniques but they failed apparently. That's the only reason I moved to DurandalJS from KnockoutJS only. Modular programming works so well without worrying about multiple viewmodels.
在多个不同的视图模型之间进行通信的另一种方法是在代码中引入 Pub-Sub .Ryan Niemeyer为此提供了一个非常好的插件,名为KO Postbox( https://github.com/rniemeyer/knockout-postbox )
Another method of communication between multiple distinct viewmodels is to introduce Pub-Sub in your code. There is a very very good plugin for that by Ryan Niemeyer called KO Postbox (https://github.com/rniemeyer/knockout-postbox)
我发现两者在不同的情况下都很有用.不过,我会采用第一种方法.
I found both useful in different scenarios. I would go with first approach though.
在多个视图模型之间共享模型:
Sharing models between multiple viewmodels :
//Shared Models for both the ViewModels
var profileModel = function(vm){
var self = this;
self.first = ko.observable("Bob");
self.last = ko.observable("Smith");
self.vm = ko.observable(vm);
};
var officeModel = function(vm){
var self = this;
self.header = ko.observable("Administration");
self.vm = ko.observable(vm);
};
var viewModel1 = function(){
var self = this;
self.profileModel = new profileModel("Called from viewModel1");
self.officeModel = new officeModel("office model Called from viewModel1");
};
var viewModel2 = function(){
var self = this;
self.profileModel = new profileModel("Called from viewModel2");
self.officeModel = new officeModel("office model Called from viewModel2");
};
//the overall view model
var viewModel = function(){
var self = this;
self.profile = new profileModel(),
self.office = new officeModel(),
self.viewModel1 = new viewModel1(),
self.viewModel2 = new viewModel2()
};
ko.applyBindings(new viewModel());
这篇关于在敲出.js中将视图模型拆分为多个视图模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!