【问题标题】:Render view with overwritten getters in Backbone在 Backbone 中使用覆盖的 getter 渲染视图
【发布时间】:2011-11-23 22:13:21
【问题描述】:

我正在构建一个小型 Backbone.js 应用程序,并向其中一个模型添加了一些自定义 getter(例如,名称 getter 返回连接的名字和姓氏):

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

  name: function() {
    return firstName + " " + lastName;
  }
})

我现在可以使用person.get("name") 来检索名称,很好。但是,当我在模型上调用 toJSON 时,这些值不包括在内(我认为这是有道理的)。问题是我用它来呈现我的观点:

this.template({people: this.collection.toJSON()});

在 Backbone.js 中执行此操作的最佳方法是什么?使用覆盖的 getter 手动创建 JSON?

谢谢!

【问题讨论】:

  • 为什么不让“名字”成为一个真正的属性呢?
  • 因为我想要不想要静态属性。如果我在此示例中更改 firstName name 应该返回更新后的名称,我不想单独更改它们。这有意义吗?

标签: json templates backbone.js render getter


【解决方案1】:

您可以在 PersonModel 上提供自己的 toJSON 方法:

toJSON: function() {
    var attr = Backbone.Model.prototype.toJSON.call(this);
    attr.name = this.name();
    return attr;
}

collection toJSON 只是在每个模型上调用toJSON

// The JSON representation of a Collection is an array of the
// models' attributes.
toJSON : function() {
  return this.map(function(model){ return model.toJSON(); });
},

所以将您自己的toJSON 添加到您的模型应该可以工作。

您还可以将name 添加为真实属性,然后调整模型的validate 方法以在firstNamelastName 更改时更新name,并忽略任何直接更改name 或抱怨的尝试当有人尝试将name 更改传递给set 时,关于“尝试编辑只读属性”。没有任何内容表明validate 不能更改它所提供的属性对象,因此您可以在validate 返回之前将其提供{firstName: 'x'} 并将其更改为{firstName: 'x', name: 'x ' + this.get('lastName')}。这有点滥用validate,但没有明确禁止validate 更改属性集,这是您拥有的唯一钩子。我想你可以让模型自己监听firstNamelastName的更改事件,然后触发set({name: ...}),但是如果其他人只看名字和姓氏,你可能会遇到事件排序问题。

【讨论】:

  • +1 用于提供所有选项,尽管我不会使用 validate 来实现这个看起来很丑的解决方案:P 虽然我喜欢第一个解决方案,但就在今天我用稍微不同的方法回答了一个类似的帖子,在 toFullJSON() 方法中调用 toJSON() ,愚蠢的我,我可以覆盖默认值并添加该死的额外属性:)
  • @Sander:我同意validate 部分不是很好,但是Backbone 中不支持虚拟属性,并且没有太多用于自己设置的挂钩;如果你需要做一些非标准的事情,constructor/parse/validate 就差不多了。我想说这是许多 ORM-ish 系统都有的通常的“对象是结构”方法的问题的一个例子。
【解决方案2】:

我选择扩展主干模型,并让我的所有应用程序模型都从包含方法的基本模型扩展,以便启用设置合并到模型toJSON 方法中的虚拟属性。

  toJSON: function() {
    return _.extend(toJSON.__super__.constructor.apply(this, arguments), this.getVirtualAttributes());
  },
  getVirtualAttributes: function() {
    var attrs, key;
    attrs = {};
    for (key in this.virtualAttributes) {
      attrs[key] = this.virtualAttributes[key].call(this);
    }
    return attrs;
  }

这允许您在模型上定义一个 virtualAttributes 对象,该对象可用于检索虚拟/动态属性。

virtualAttributes: {
  email_length: function() {
    return this.get("email").length
  }
}

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多