7

在我的 Backbone 应用程序中,我有一个由几个子模型作为参数组成的模型。

我是这样定义的:

app.Models.Account = Backbone.Model.extend({

    initialize : function( ) {
        this.set( { 
                info     : new app.Models.Info(),
                logins   : new app.Collections.Logins(),
                billing  : new app.Models.Billing(),
            } );
    }

});

问题是在获取和保存时。例如,当我获取 JSON 响应时,包括一个对象info、一个数组logins和一个对象billing。Backbone 自动将它们分配为普通参数,这意味着子模型被一个简单的对象覆盖。

我目前的解决方案是fetch像这样覆盖模型的方法:

    fetch: function( options ) {
      options = options ? _.clone(options) : {};
      var model = this;
      var success = options.success;
      options.success = function(resp, status, xhr) {
        resp = model.parse( resp, xhr );

        model.get('info').set(resp.info);

        model.get('logins').reset(resp.logins);

        model.get('billing').set(resp.billing);

        if (success) success(model, resp);
      };

      options.error = Backbone.wrapError(options.error, model, options);
      return (this.sync || Backbone.sync).call(this, 'read', this, options);
    }

但是,这仅用于获取。并且由于在调用该save()方法时会返回创建的模型的更新状态,因此我还必须覆盖该save()方法。

有什么好的方法可以解决这个问题吗?

也许覆盖该set()方法可能会起作用,但是我担心这意味着我将开始偏离 Backbone 代码库。

我也想过像这样使用 parse 方法

    parse : function ( response ) {
        this.model.get('info').set(response.info);
        response.info = this.model.get('info');

        this.model.get('logins').reset(response.logins);
        response.logins = this.model.get('logins')

        this.model.get('billing').set(response.billing);
        response.billing = this.model.get('billing');

        return response;
    }

这将创建对已更新子模型的引用。

4

1 回答 1

3

我通常parse用于子模型,如您的第二个示例(尽管请注意您需要response在最后返回)。我认为这在概念上是准确的,parse将服务器端表示转换为客户端表示的适当位置也是如此。我相信这也应该适用save,尽管我还没有测试过,因为parse保存响应也被调用了。

以我的经验,压倒set一切不过是麻烦——它往往会产生意想不到的副作用,最好避免。

于 2012-11-23T22:07:21.897 回答