Backbone.js在解析后为模型添加计算属性

时间:2013-12-04 13:10:50

标签: javascript backbone.js

在Backbone中,有一种方法可以在解析相同模型后在模型上执行函数。

我有基础数据的模型,并且想要计算组合基础数据的另一个属性。

目前我在模型中有一个函数设置来创建和添加属性,这是在通过循环遍历每个模型从服务器获取数据后执行的,但它并不理想。

var Report = Backbone.Model.extend({

    generateURL: function(){
        var sURL = '', sHash = '';

        sHash += this.get('reportid');
        sHash += 'p1' + app.venue.info.get('loginid');

        sURL += 'r=' + this.get('reportid');
        sURL += '&p1=' + app.venue.info.get('loginid');

        _.each(this.params, function(param){
            sURL    += '&' + param.name + '=' + param.value;
            sHash   += param.name + param.value;
        });

        sURL += '&h=' + new jsSHA((sHash + this.collection.sKey),'TEXT').getHash('SHA-1','HEX');

        this.set({"url":sURL});

    }

});

var Reports = Backbone.Collection.extend({

    model: Report,
    sKey: '***********',
    url: function(){
        return '/reports/venue/'+ app.venue.info.id;
    },

});

app.venue.reports.set([{id:0,reportid:3,params:null,report_name:'Report3'},{id:1,reportid:2,params:null,report_name:'Report2'}]);

app.venue.reports.each(function(report){ report.generateURL(); });

3 个答案:

答案 0 :(得分:1)

您当然可以覆盖.parse()功能并执行任何操作。

var Mod = Backbone.Model.extend({
    parse: function(response){
        response.new_attr = response.old_attr + 1;
        return response;
    }
})

答案 1 :(得分:0)

Dazzer13,Stephen的方法是正确的(这是解析函数的主要用途之一)。

对于您的第一个问题,parse()返回的任何内容都将用作模型的基础数据。因此,假设您的回复包含:

{ 
  id: 1556,
  first_name: "John"
  last_name: "Doe"
}

您可以使用parse修改此哈希并添加新的计算值,例如

parse: function(response) {
  response.initials = response.first_name[0]+response.last_name[0];
  return response;
}

这与使用以下哈希创建模型完全相同:

{ 
  id: 1556,
  first_name: "John"
  last_name: "Doe"
  initials: "JD"
}

这意味着在那之后,你可以做一个model.get(“initials”)并且它将包含你的计算值。如果你做一个model.save(),它会将数据中的首字母发送到服务器:实际上,内部Backbone总是在服务器的响应上调用解析,但是默认解析只是做一个'return response;'。这就是为什么这些新属性与普通属性完全一样,因为它们与其他属性的机制相同。

对于你的第二个问题,调用Collection.set()(或add)确实不会调用parse ...除非你给它选择{parse:true}!原因是假设set()(至少基于文档)用于使用骨干模型设置集合,而不是使用javascript原始对象。事实上,它可以动态地将javascript原始对象转换为骨干模型,这比其他任何东西都更方便。

答案 2 :(得分:0)

尝试Alex Beletski的backbone-computedfields。 它非常广泛且强大,可处理事件,更改,依赖项,JSON和验证。项目页面的简短示例:

array (size=5)
  0 => 
    array (size=3)
      0 => int 1
      1 => int 2
      2 => int 3
  1 => 
    array (size=3)
      0 => int 4
      1 => int 5
      2 => int 6
  2 => 
    array (size=3)
      0 => string '' (length=0)
      1 => string '' (length=0)
      2 => string '' (length=0)
  3 => 
    array (size=3)
      0 => string '' (length=0)
      1 => string '' (length=0)
      2 => string '' (length=0)
  4 => 
    array (size=3)
      0 => string '' (length=0)
      1 => string '' (length=0)
      2 => string '' (length=0)