处理Backbone中的不可保存值

whe*_*hys 7 javascript database backbone.js

是否有一种标准方法来处理Backbone中的不可保存值.

例如

MyModel = Backbone.extend(Backbone.Model, {
    initialize: function () {
        this.set({'inches': this.get('mm') / 25});
    }
})
Run Code Online (Sandbox Code Playgroud)

如果我在这个模型上调用save(),它将抛出一个错误,因为没有相应的数据库字段inches.我可以想出几种方法来解决这个问题,但我想知道是否有一种经过试验和测试的方法通常最适合这种方法?

目前我的首选解决方案是扩展Backbone的toJSON方法并允许传递布尔参数,dontCleanup以允许它在需要时仍然返回所有模型的值(包括不可保存的值),例如传递给模板.

Der*_*ley 11

我喜欢彼得里昂的想法.我已经考虑了几次,但从未真正把它放到位.不过,对于我处理这个问题的所有方法,这是我最喜欢的两个方面:

  • 非"属性"值
  • 查看模型

非属性值

这个很简单:不要在模型的标准属性中存储您需要的值.而是将其直接附加到对象:


myModel.someValue = "some value";
Run Code Online (Sandbox Code Playgroud)

这里的一个大问题是,您没有获得与调用set模型相关的所有事件.所以我倾向于将它包装在一个为我做所有事情的方法中.例如,我在模型上使用的常用方法是select说已选择此模型:


MyModel = Backbone.Model.extend({
  select: function(){
    if (!this.selected){
      this.selected = true;
      this.trigger("change:selected", this, this.selected);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

在你的情况下,我不确定这是一个好方法.您的数据需要根据属性中的值进行计算.

为此,我倾向于使用视图模型.

查看模型.

基本思想是,您可以像往常一样创建一个可持久的骨干模型.但是你来了并创建了另一个继承了原始模型的模型,并添加了所需的所有数据.

您可以通过多种方式实现此目标.这可能是一个非常简单的版本:


MyModel = Backbone.Model.Extend({ ... });

MyViewModel = function(model){
  var viewModel = Object.create(model);

  viewModel.toJSON = function(){
    var json = model.toJSON();
    json.inches = json.mm / 25;
    return json;
  };

  return viewModel;
});
Run Code Online (Sandbox Code Playgroud)

包装它的最大好处Object.create是您现在具有原型继承情况,因此模型中的所有标准功能仍然存在.我们刚刚toJSON在视图模型上重写了该方法,以便它返回带有该inches属性的JSON对象.

然后在需要这个的视图中,您可以将模型包装在initialize函数中:


MyView = Backbone.View.extend({
  initialize: function(){
    this.model = MyViewModel(this.model);
  },

render: function(){ var data = this.model.toJSON(); // returns with inches } });

new MyViewModel(this.model)如果你愿意,你可以调用,但最终不会做任何不同的事情,因为我们显式地从MyViewModel函数返回一个对象实例.

当您的视图的渲染方法调用时toJSON,您将获得该inches属性.

当然,这个实现存在一些潜在的内存问题和性能问题,但是这些可以通过一些更好的代码用于视图模型来轻松解决.然而,这个快速而肮脏的例子应该让你走上正轨.