0

我在客户端上有一个骨干集合。集合的模型与另一个集合一起具有一些属性

当我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 集合变成了一个普通的属性(数组)

4

1 回答 1

1

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

首先-“get”不会从模型中获取属性。它从模型的属性中获取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 集合上的事件,也不会允许您使用类似的助手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);
    }
});

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

于 2012-10-19T21:41:38.713 回答