【问题标题】:How to mass assign all attributes of a Backbone model?如何批量分配 Backbone 模型的所有属性?
【发布时间】:2013-08-05 10:47:57
【问题描述】:

只要signIn成功,我想更新User 模型。它包括由后端分配的id,以前模型中没有。

MyApp.module("User", function(User, App, Backbone, Marionette, $, _) {

  User.Controller = Backbone.Marionette.Controller.extend({

    initialize: function() {
      this.model = new MyApp.User.Model();
    },

    signIn: function(credentials) {
      var signInData = { user: credentials };
      var self = this;

      App.session.signIn(signInData, {
        success: function(model, response, options) {
          self.updateUserModel(model);
        },
        error: function(model, xhr, options) {}
      });
    },

    updateUserModel: function(model) {
      // TODO Update all attributes, including new onces e.g. id.
    }

  });
});

如何一次更新所有属性?我知道我可以手动 set 每个属性,但这似乎是错误的,因为属性列表可能会随着时间而改变。
一般来说,我希望User 模型中有这样的update(model) 方法。


当我按照 nikoshrjohn-4d5 的建议使用 Backbone 的 model.set() 方法时...

    signIn: function(credentials) {
      var signInData = { user: credentials };
      var self = this;

      App.session.signIn(signInData, {
        success: function(model, response, options) {
          self.model.set(model);
        },
        error: function(model, xhr, options) {}
      });
    },

...id 属性已复制到 this.model,但缺少其他属性,例如 name

success 回调中返回的模型如下所示:

_changing: false
_pending: false
_previousAttributes: Object
attributes: Object
    bind: function (name, callback, context) {
    close: function (){
    constructor: function (){ return parent.apply(this, arguments); }
    created_at: "2013-07-22T19:03:24Z"
    email: "user@example.com"
    id: 3
    initialize: function () {
    listenTo: function (obj, name, callback) {
    listenToOnce: function (obj, name, callback) {
    logout: function () {
    model: child
    name: "Some User"
    off: function (name, callback, context) {
    on: function (name, callback, context) {
    once: function (name, callback, context) {
    options: Object
    signIn: function (credentials) {
    signUp: function (credentials) {
    stopListening: function (obj, name, callback) {
    trigger: function (name) {
    triggerMethod: function (event) {
    unbind: function (name, callback, context) {
    updated_at: "2013-08-05T13:20:43Z"
    user: Object
    __proto__: Object
    changed: Object
cid: "c3"
id: 3
__proto__: Surrogate

【问题讨论】:

  • 我可能遗漏了什么,但this.model.set(model); 有什么问题?
  • @nikoshr 实际上我在文档中没有看到这一点。我试过了,但它并没有复制其他属性然后id。例如 name 在更新的模型中丢失。
  • 那么,model 包含什么(成功回调中的第一个参数)?

标签: backbone.js model attributes


【解决方案1】:
  • 您正在Backbone.Model 附近移动,
  • Model.set 接受属性哈希,
  • 您可以将Backbone.Model 转换为带有Model.toJSON 的属性哈希值

你可以把你的回调写成

success: function(model, response, options) {
    self.model.set(model.toJSON());
}

【讨论】:

  • 我找到了一个可行的替代方案:self.model.set(model.attributes)。这似乎是我想要完成的任务。
  • 您的评论是否意味着您不鼓励使用.attributes
  • 这是一种内部表示。它可能适用于您的情况,但不能保证它在未来版本的 Backbone 中保持不变。我倾向于谨慎并倾向于Model.toJSON
  • 我实际上无法从文档中阅读此内容。相反.toJSON()对我来说似乎更不稳定,例如.toString()
  • 我相信我在处理模型(用户、会话)时存在架构错误。我现在更改了设置。我会接受你的回答,因为这对我来说很有意义。
【解决方案2】:

您可以简单地使用set,将另一个模型的attributes 属性值(具有所有属性值的对象)作为参数。

self.model.set(model.attributes);

【讨论】:

    【解决方案3】:

    您可以像@nikoshr 所说的那样使用this.model.set(model)。遍历属性并设置每个属性将做与 model.set 已经做的事情相同的事情。参考主干的model.set函数:

    // Set a hash of model attributes on the object, firing `"change"`. This is
    // the core primitive operation of a model, updating the data and notifying
    // anyone who needs to know about the change in state. The heart of the beast.
    set: function(key, val, options) {
      var attr, attrs, unset, changes, silent, changing, prev, current;
      if (key == null) return this;
    
      // Handle both `"key", value` and `{key: value}` -style arguments.
      if (typeof key === 'object') {
        attrs = key;
        options = val;
      } else {
        (attrs = {})[key] = val;
      }
    
      [...]
    
      // For each `set` attribute, update or delete the current value.
      for (attr in attrs) {
        val = attrs[attr];
        if (!_.isEqual(current[attr], val)) changes.push(attr);
        if (!_.isEqual(prev[attr], val)) {
          this.changed[attr] = val;
        } else {
          delete this.changed[attr];
        }
        unset ? delete current[attr] : current[attr] = val;
      }
     [...]
    }
    

    另一种选择是实例化一个新模型:

    this.model = new MyApp.User.Model(model);
    

    【讨论】:

      猜你喜欢
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多