在敲出.js中将视图模型拆分为多个视图模型 [英] Split viewmodel into multiple viewmodels in knockout.js

查看:47
本文介绍了在敲出.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆