在骨干非saveable值处理(Dealing with non-saveable values i

2019-06-24 04:58发布

是否有应对骨干非saveable值的标准方法。

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

如果我调用保存()这个模型,因为是没有相应的数据库字段,将抛出一个错误inches 。 我能想到的一些方法来解决这个问题,但我想知道如果有一个久经考验的方法通常最适合用于本?

此刻我的首选解决方案是延长骨干toJSON方法,并允许一个布尔参数的传递dontCleanup允许它仍然会返回模型的所有值(包括非saveable的)时,它需要例如用于传递给一个模板。

Answer 1:

我喜欢彼得·里昂的想法。 我已经想过了几次,但从来没有真正把它在的地方。 对于我已经处理了这个的所有方式,不过,这里有我的两个最爱:

  • 非“属性”值
  • 视图模型

非属性值

这一个很简单:不存储在模型中的标准属性需要的值。 相反,它直接连到对象:


myModel.someValue = "some value";

这里最大的问题是,你没有得到所有调用相关的事件的set在模型上。 所以,我倾向于在这做了我的一切的方法来包装这件事。 举例来说,我穿上机型常用的方法是select地说,这种模式已经被选择:


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

在你的情况,我不知道这将是一个不错的办法。 你有数据,需要根据,在您的属性已经值来计算的。

对于这一点,我倾向于使用视图模型。

查看模型。

其基本思想是您创建一个骨干模式,即坚持-能,因为你通常会。 但是你一起去,并创建从原来的一个继承,并增加了所有你需要的数据另一种模式。

有一个非常大的数量的方式,你可以做到这一点。 以下是可能是一个非常简单的版本:


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;
});

与此包裹的最大好处Object.create是,你现在有一个原型继承的情况,因此,所有的从模型的标准功能还是很到位的。 我们刚刚在覆盖toJSON在视图模型方法,使其返回与JSON对象inches属性。

然后在需要这样的观点,你会在包装的初始化函数模型:

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

渲染:函数(){风险数据= this.model.toJSON(); //与返回inches }});

你可以称之为new MyViewModel(this.model)如果你想要的,但是这不会做任何事情一样,在最后,因为我们明确地从返回一个对象实例MyViewModel功能。

当您的视图的渲染方法调用toJSON ,你会得到inches与它的属性。

当然,也有一些潜在的内存问题和性能问题与此实现,但那些可以很容易地与视图模型的一些更好的代码来解决。 这种快速和肮脏的例子应该让你失望的道路,虽然。



Answer 2:

我想,这应该这样做。 定义你的Model defaults为您有效的模式,然后只返回的子集this.attributes期间是有效toJSON

var Model = Backbone.Model.extend({
  defaults: {
    foo: 42,
    bar: "bar"
  },

  toJSON: function () {
    var schemaKeys = _.keys(this.defaults);
    var allowedAttributes = {};
    _.each(this.attributes, function (value, key) {
    if (_.include(schemaKeys, key)) {
      allowedAttributes[key] = value;
    }
    return allowedAttributes;
  }
});

需要注意的是_.pick会使代码短一点,一旦你有下划线1.3.3可用。 我还没有看到过骨干的社区我的旅行是“久经考验”约定,自骨干留下这么多的选择余地,有时约定不出现,但我们会看看这个计算器问题的产量。



Answer 3:

在Backbone.js的非持久化处理的属性已经做我的头了一段时间,特别是因为我一直在使用烬/烬数据,它通过计算性能,烬数据属性,或控制器处理各种情况下启动。

许多解决方案建议定制toJSON方法。 然而,一些流行的骨干插件(特别是那些与嵌套模型处理),实现自己toJSON方法,使一个呼叫Backbone.Model.prototype.toJSON获得一个模型的属性的对象表示。 因此,通过覆盖toJSON模型中定义的方法,你就会失去这些插件的一些(潜在的关键)功能。

我拿出最好是包括excludeFromJSON模型定义按键的排列,并覆盖toJSON的方法Backbone.Model.prototype本身:

Backbone.Model.prototype.toJSON = function() {
  var json = _.clone(this.attributes),
      excludeFromJSON = this.excludeFromJSON;
  if(excludeFromJSON) {
    _.each(excludeFromJSON, function(key) {
      delete json[key];
    });
  }
  return json;
};

MyModel = Backbone.Model.extend({
  excludeFromJSON: [
    'inches'
  ]
});

通过这种方式,你只需要定义非持续键(如果你忘了这样做,你很快就会在您的服务器抛出一个错误提醒!)。 toJSON将表现为正常的,如果没有excludeFromJSON属性存在。


在你的情况, inches是计算性能,源自mm ,所以是有意义的落实,这个是你的模型的方法(确保当毫米改变英寸的值是正确的):

MyModel = Backbone.Model.extend({
  inches: function() {
    return this.get('mm') / 25;
  }
});

然而,这具有不同的方式访问到everyother属性下行。 理想情况下,你会希望保持它与访问其他属性保持一致。 这可以通过以下方式实现扩展默认get方法 :

var getMixin = {
  get: function(attr) {
    if(typeof this[attr] == 'function') {
      return this[attr]();
    }
    return Backbone.Model.prototype.get.call(this, attr);
  }
};

MyModel = Backbone.Model.extend({
  inches: function() {
    return this.get('mm') / 25;
  }
});
_.extend(MyModel.prototype, getMixin);

这将让你做的事:

new MyModel().get('inches');

这种方法不触及根本attributes哈希,这意味着inches不会出现在toJSON表示, 除非set的值inches后来,在这种情况下,你需要的东西像excludeFromJSON阵列。

如果您有需要setinches值,你可能还需要监听的变化和调整的价值mm

MyModel = Backbone.Model.extend({

  initialize: function() {
    this.on('change:inches', this.changeInches, this);
  },

  inches: function() {
    return this.get('mm') / 25;
  },

  changeInches: function() {
    this.set('mm', this.attributes.inches * 25);
  }
});
_.extend(MyModel.prototype, getMixin);

请参阅上JSBin完整的例子 。

另外值得一提的是, 在的(官员?)目的toJSON方法最近被重新定义为准备模型与服务器同步。 出于这个原因,调用toJSON应该总是返回只有“持久化”(或“saveable”)的属性。



文章来源: Dealing with non-saveable values in Backbone