Backbone.js + MVC3。嵌套集合未填充

时间:2012-10-19 19:17:17

标签: asp.net-mvc-3 backbone.js

我在客户端有一个骨干集合。 该集合的模型具有一些属性以及另一个集合

当我执行fetch()我的服务器上的操作方法返回一些数据时,集合将被填充,所有属性也是如此,除了嵌套集合。

可能是什么原因?

var Job = Backbone.Model.extend();
var Jobs = Backbone.Collection.extend({model: Job})

var Foo = Backbone.Model.extend({ 
    initialize:function(){
      this.jobs = new Jobs();
}})
var FooCollection = Backbone.Collection.extend({model: Foo})

var fooCol = new FooCollection()
fooCol.fetch();

fooCol.first().get('name') // => returns name
fooCol.first().jobs.toJSON() // returns nothing
// although this will
fooCol.first().get('jobs') //it will return an array

因此,嵌套的Backbone集合变成了一个常规属性(Array)

1 个答案:

答案 0 :(得分:1)

好的 - 有了你的额外信息,我可以给你一个答案。

首先 - “获取”不会从模型中获取属性。它从模型的attributes属性中获取属性。因此,属性可能如下所示:

{
    name: 'blah',
    jobs: [{name: 'job1'}, {name: 'job2'}]
}

Backbone不会自动将数组转换为集合和模型,只是设置this.jobs不起作用。你需要做的事情有点复杂。

var Foo = Backbone.Model.extend({ 
    initialize:function(){
      this.jobs = new Jobs(this.attributes.jobs));
    }
});

这会将您的'jobs'属性设置为一个新的作业对象,其中包含为作业发送的数据。但是,唉,它不会自动触发Jobs集合上的事件,也不会允许你使用像this.get('jobs').each(fn);这样的帮助器 - 你只能将它用作Foo.jobs.each(fn)

为了让你将该属性用作实际的集合,你将不得不做更复杂的事情。

var Foo = Backbone.Model.extend({ 
    initialize:function(){
      this.createJobs(this.attributes.jobs);
    },
    toJSON: function () {
        var json = Backbone.Model.prototype.toJSON.apply(this);
        json.jobs = this.get('jobs').toJSON();
        return json;
    },
    set: function (key, val) {
        var attributes;
        if(!_.isObject(key)) {
            attributes = {}; attributes[key] = val;
        } else {
            attributes = key;
        }
        safeAttributes = _.omit(attributes, 'jobs');
        Backbone.Model.prototype.set.call(this, safeAttributes);
        if(attributes.jobs) { this.get('jobs').reset(attributes.jobs); }
    },
    clear: function () {
        if(this.get('jobs') && this.get('jobs').destroy) {
            this.get('jobs').off(); 
            this.get('jobs').destroy(); 
        }
        Backbone.Model.prototype.clear.apply(this);
        this.createJobs();
    },
    createJobs: function (jobsArray) {
        var jobsCollection = new Jobs(jobsArray);
        jobsCollection.on('change', function () {this.trigger('change'); }, this);
        this.set('jobs', jobsCollection);
    }
});

请注意,这是完全未经测试的,但希望它会显示您执行此操作的一些方法。