2

我有一个 JSON 文件,它将创建我ParentModel的以及填充子集合Records

ParentModel : Backbone.Model.extend({
  initialize: function() {
    this.set({ records: new Records(this.get("records")) });
  }
});

Records 集合只是映射到 Record 模型的基本 Backbone 集合。

问题是我需要孩子知道父母,所以每个Record模型都必须有一个父属性。所以现在我刚刚将它添加到初始化方法的底部:

var self = this;
this.get("records").each(function(record) {
  record.set("parent", self);
});

这很好用,但是当我创建新记录时,我宁愿不必记住包含这 4 行。

这个答案说我可以重写初始化方法以接受额外的参数,但我不太确定如何让 Backbone 自动将 ParentModel 传递给重写的初始化方法。谁能提供一个如何做到这一点的例子?

我听说过Backbone-relational可能有助于做我想做的事,但这是另外 23kb 的内容。如果这是更好的方法,我会考虑实现它,但如果有可用的解决方案,我更喜欢更简单的解决方案。

ParentModel无论我是通过代码创建新记录,还是它是由 JSON 提要自动创建的,这都需要工作。

4

2 回答 2

4

我通常发现将结构元素移出属性更清晰,因此我的记录和父属性位于对象上,而不是属性上。也就是说,您可以利用集合和父对象上的不同事件:

var ParentModel = Backbone.Model.extend({
    initialize: function () {
        _.bindAll(this, 'adoptOne', 'adoptAll');
        this.records = new Records();

        this.on('change:records', function () {
             this.records.reset(this.get('records'));
        });
        this.records.on('reset', this.adoptAll);
        this.records.on('add', this.adoptOne);

        this.records.reset(this.get('records'));
    },

    adoptAll: function () {
       this.records.each(this.adoptOne);
    },
    adoptOne: function (model) {
        model.parent = this;
    }
});

一些测试:

var p = new ParentModel({
    name: "I am the parent",
    records: [{id: 1}, {id: 2}]
});

p.records.add({id: 3});

p.records.each(function (child) {
    console.log(child.get('id')+' '+child.parent.get('name'));
});

p.set({records: [{id: 4}]});

p.records.each(function (child) {
    console.log(child.get('id')+' '+child.parent.get('name'));
});

还有一个小提琴http://jsfiddle.net/sPXaZ/

于 2012-07-10T16:21:07.443 回答
1

为了清楚起见,这里是您的需求之一的摘要(可以在问题评论中找到):

例如,如果我想居中定位一个 Record 元素,我需要知道 viewbox 的宽度。知道这一点的唯一方法是知道最宽的记录元素是什么。父对象可以通过对其子元素进行排序来告诉我这一点。

在我看来,您的模型必须处理显示问题;Backbone 中的显示由 Views 处理。所以,我想你可以创建一个既听又听的ParentModel视图Records

var RecordView = Backbone.View.extend({
  initialize: function() {
    this.collection.on('sync', this.render, this);
  }
  render: function() {
    var widest = this.model.get('width');
  }
});

var view = new RecordView({model: ParentModel, collection: Records});

而且,在我看来,这不是为了ParentModel处理它在屏幕上的宽度,而是为了它自己的视图。在这里介绍两个 View 似乎是重点。

但我没有完整的图片,所以,如果我错了,请给我更多你想要做的事情的样本。

于 2012-07-12T08:00:19.177 回答