【问题标题】:Backbone fetch model then render view主干获取模型然后渲染视图
【发布时间】:2016-05-01 18:35:45
【问题描述】:

在模型上执行提取操作时,我可以看到 API 返回 JSON 格式的所需数据。记录模型的控制台会在“已更改”对象中显示新数据。

获取前后:

Object {
  cid: "c1",
  attributes: Object,
  _changing: false,
  _previousAttributes: Object,
  changed: Object,
  id: undefined,
  _pending: false
}

Object {
  cid: "c1",
  attributes: Object,
  _changing: false,
  _previousAttributes: Object,
  changed: Object[1],
  id: undefined,
  _pending: false
}

显然正在获取数据,并且它存在于模型中。但是,在渲染时,会显示默认值。

App.Models.Document = Backbone.Model.extend({

  defaults: {
     id: '',
     owner: 0,
     created: '',
     lastupdate: '',
     content: 'Default document content'
  },

  url: '/api/'

});


App.Views.DocumentView = Backbone.View.extend({

  tagName: 'textarea',
  className: 'editor',

  template: App.Template('editortemplate'),

  initialize: function() {

  // As proposed in so many similar questions
  this.listenTo(this.model, "change", this.render);

  },
  render: function() {

    this.$el.html( this.template( this.model.toJSON() ) );

    $(".app-content").html(this.$el);

    return this;

  }
});


a = new App.Models.Document();
a.fetch();
b = new App.Views.DocumentView({ model: a });
b.render();

如何使用新数据正确更新视图?

如果我从模型中删除默认值,则未定义“内容”。

【问题讨论】:

  • 奇怪的是changed: Object 变成了changed: Object[1],。 API 返回的数据结构是怎样的? BTW id 是主干使用的特殊属性。
  • 返回的数据是一个json对象 [{ "id":"1", "owner":"1", "created":"2016-04-30 21:57:23", "lastupdate":null, "content":"API 获取成功" }]
  • 这意味着您需要在 Backbone 将响应设置为模型属性之前实现 parse() 来处理响应,或者您需要从 Collection 获取该 REST 资源。

标签: javascript backbone.js


【解决方案1】:

Backbone.Model 期望从服务器返回一个对象,而不是一个数组。集合的情况下应该返回一个数组。

所以在你的情况下,你需要定义一个parse 方法来返回包含数据的对象:

App.Models.Document = Backbone.Model.extend({
  defaults: {
    owner: 0,
    created: '',
    lastupdate: '',
    content: 'Default document content'
  },
  url: '/api/',
  parse: function(response) {
    return response[0];
  }

});

【讨论】:

  • 非常感谢您的提示!
【解决方案2】:

您可以在模型上监听 Backbone sync 事件。 sync 在成功调用服务器后触发

this.listenTo(this.model, 'sync', this.render);

您还可以在初始化方法中将模型获取移动到App.Views.DocumentView。 比,成功时你渲染视图:

App.Models.Document = Backbone.Model.extend({
  defaults: {
    id: '',
    owner: 0,
    created: '',
    lastupdate: '',
    content: 'Default document content'
  },

  url: '/api/'
});


App.Views.DocumentView = Backbone.View.extend({
  tagName: 'textarea',
  className: 'editor',
  template: App.Template('editortemplate'),
  initialize: function() {
    var self = this;

    // model fetch
    this.model.fetch({
      success: function() {
        // call render
        self.render();
      },
      error: function () {
        // handle error
      }
    });

    // As proposed in so many similar questions
    this.listenTo(this.model, "change", this.render);
  },
  render: function() {
    this.$el.html(this.template(this.model.toJSON()));
    $(".app-content").html(this.$el);
    return this;
  }
});


var myModel = new App.Models.Document();
var myView = new App.Views.DocumentView({
  model: myModel
});
myView.render();

【讨论】:

  • 谢谢 Yosvel。不幸的是,什么都没有真正改变。显示默认值。执行了提取,模型对象有一个我仍然无法访问的“更改”值。
猜你喜欢
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
  • 1970-01-01
相关资源
最近更新 更多