解析后,骨干收集模型消失

时间:2013-11-28 22:58:31

标签: javascript json backbone.js backbone-collections backbone-model

我有这个模型和它的集合:

app.models.Result= Backbone.Model.extend({

    idAttribute: 'uid',

    initialize: function () {
        this.set('name', this.get('name').replace(' ', '').substring(0, 20));
    },

});

app.models.ResultList = Backbone.Collection.extend({

    model: app.models.Result,
    url: 'http://localhost/stuff',

    parse: function (response, options) {
        this.add(response.data);
        console.log(this);
        return response.data;
    },

});

然后我在我的视图initialize()函数中使用它:

var that = this;
this.collection = new app.models.SearchList();
this.collection.fetch({
    dataType: 'jsonp',
    success: function () {
        console.log(that.collection);
        that.collection.each(function (resultModel) {
            console.log('ok');
        });
    }
});

使用这段代码,我几乎得到了我想要的东西,但当我查看第二个log()时,我可以看到name属性与获取的JSON中的属性相同。

First try's logs

我的猜测是因为我只是返回response.data,因此我将其修改为this。在这种情况下,我收到一个错误:

  

未捕获的TypeError:无法调用未定义的方法'replace'

所以我评论了这一行。现在我可以看到所有的模型都消失了。该数组中只有一个模型,但不是JSON中的模型。

Second try's logs

我心爱的模特发生了什么?他们在哪?我应该以某种方式保存它们吗?在第一个日志this指向正确的完整集合,那么为什么不返回this给我相同的正确集合。

1 个答案:

答案 0 :(得分:2)

response.data返回Collection.parse时,您是对的。引用the documentation

  

该函数传递原始响应对象,并应返回要添加到集合中的模型属性数组

我认为您的问题是您在this.add内拨打Collection.parse - 您不需要这样做,因为调用Collection.parse的函数会处理add你。

我认为执行此操作时发生的情况是,在您调用Collection.set时会添加模型,但随后集合会调用Collection.set - 这会导致您修改过的所有名称值将被服务器版本替换。

要回复您的评论:Collection.fetch被称为Collection.reset的一部分 - 这就是Backbone默认工作的方式(如果您愿意,可以让它调用Collection.add,通过一个选项)。解决问题的最简单方法就是从parse函数中移除Collection.set来电 - 这样initialize将按预期行事。

this.add函数只是在初始化模型时调用。如果要在首次创建模型时更改模型的属性,这是一个可以执行此操作的位置。但是,您通过调用parse创建模型,然后通过从parse返回数据来更新该数据 - 这会导致初始化更改被覆盖。

另一种方法是更新name函数以根据需要转换数据,然后返回。

或者,如果设置的值为{{1}}

,您可以覆盖模型中的set函数来转换传递的数据。