【问题标题】:Backbone partial view not rendering the latest model骨干局部视图未渲染最新模型
【发布时间】:2016-01-23 11:31:27
【问题描述】:

我对 Backbone 比较陌生,我遇到了这个问题。

我在 DustJS 中使用 Backbone

我的模板看起来像这样 - index.dust

<div id="parentView">
  <div class="section">
    {>"app/inc/responseMessage" /}
    <div class="userDetails">
      {! A button to get user details !}
    </div>
  </div>
</div>

这是我下面的部分 - responseMessage.dust

<div id="responseMessage">
  {@eq key="{data.success}" value="true"}
    <div class="alert alert-success success" role="alert">success</div>
  {/eq}
</div>

我的 JS 是这样的

initialize: function() {
    this.responseMessageView = this.responseMessageView ||
        new ResponseMessageView({
            model: new Backbone.Model()
        }); // View is for the partial
    this.model = this.model || new Backbone.Model(); //View for the whole page
},

当事件发生时调用下面的函数并执行 POST 并成功返回。

primaryViewEventTrigger: function(event){
  //Button click on `index.dust` triggers this event and does a POST event to the backend

  this.listenToOnce(this.model, 'sync', this.primaryViewSuccess);//this will render the whole view. 
  this.listenToOnce(this.model, 'error', this.primaryViewError);
  this.model.save({data: {x:'123'}});
}

responseViewEventTrigger: function(event){
  //Button click on `responseMessage.dust` triggers this event and does a POST event to the backend

  this.listenToOnce(this.responseMessageView.model, 'sync', this.responseViewSuccess);//it should only render the partial view - responseMessage.dust
  this.listenToOnce(this.responseMessageView.model, 'error', this.primaryViewError);
  this.responseMessageView.model.save({data: {x:'123'}});
}
primaryViewSuccess: function(model,response){
    this.model.set('data', response.data);
    this.render();
}
responseViewSuccess: function(model,response){
    this.responseMessageView.model.set('data', response.data);
    console.log(this.responseMessageView.model);
    this.responseMessageView.render(); // Does not work in some cases
}

我的回调函数实现

exports.sendEmail = function sendEmail(req, res){
  req.model.data.success = true;
  responseRender.handleResponse(null, req, res);
};

this.model属于整个页面的模型。而this.responseMessageView.model 是部分模型。

问题:这在大多数情况下都可以正常工作。在一种情况下,它不会使用最新的模型值渲染部分。当我单击index.dust 上的按钮时,primaryViewSuccess 被执行。之后我点击另一个按钮并触发responseViewEventTrigger。它成功完成 POST 并到达responseViewSuccess 并将其存储在模型中。但它没有在前端显示。 data.success 仍然不正确,而 console.log(this.responseMessageView.model) 表明 attributes-&gt;data-&gt;success = true

但是当我刷新页面时,同样的行为一切正常。只是当primaryViewSuccess 被调用然后responseViewSuccess 它没有接受最新的模型更改。 换句话说,模型正在更新,但 DOM 保持不变。

我在这里缺少什么?感谢您的宝贵时间!

【问题讨论】:

  • 您是有意将新模型传递给responseMessageView ,还是希望您在此代码中引用的模型相同..?您似乎在做this.model.set('data', response.data); this.responseMessageView.model.set('data', response.data); 等,看起来一团糟......我们不知道第一个代码块中包含initializething 是什么......我们不知道'不知道包含第二个代码块的 thing 是什么。你可能想先解释这些视图、模型等之间的关系
  • @t-j 我已经编辑了这个问题。我不明白你说的东西是什么意思? initialize() 用于声明整个页面和部分页面的视图。对不起,如果我不能很好地解释自己。
  • By thing 我在问它是否是视图、集合等...我没有明白你所说的“只是在调用 primaryViewSuccess 时然后 responseViewSuccess 它没有采用最新的模型更改。” 哪个视图没有采用哪个模型更改..?您有 2 个视图和 2 个模型。请在此基础上说明,谁应该根据谁更新。
  • 我不明白的一件事是为两个视图使用不同模型的原因...它们似乎使用相同的数据this.model.set('data', response.data);...如果您使用相同的模型,那么它'将更容易保持两个视图同步。此外,您不必手动将response.data 设置为模型。你可以从parse方法返回response.data,它会被自动设置。
  • 请告诉我您的 POST 回调是如何编写的

标签: javascript jquery backbone.js backbone-views


【解决方案1】:

您遇到了经典的 Backbone render-with-subviews 陷阱:当您渲染索引视图时,您正在替换 所有 DOM 节点。这包括您的 responseMessageView 实例所绑定的 DOM 节点。如果您检查responseMessageView.el,您实际上会看到它已使用新模型数据进行了更新,但是该元素不再附加到索引的 DOM 树中。

var Parent = Backbone.View.extend({
  template: _.template(''),
  render: function() {
    this.$el.html(this.template());
  },

  initialize: function() {
    this.render();
    this.child = new Child();
    this.$el.append(child.el);
  }
});

这里当你手动调用 render 时,child.el 将不再出现在 parent.el(可以使用inspector查看)。

这里最简单的解决方法是在父级使用新渲染的div#responseMessage 元素渲染后调用child.setElement。更好的解决方法是预先分离 responseMessageView 的元素,然后重新附加:

var Parent = Backbone.View.extend({
  render: function() {
    this.responseMessageView.$el.detach();
    this.$el.html(this.template(this.model.toJSON()));
    this.$el.find('#responseMessage').replaceWith(this.responseMessageView.el);
  }
});

【讨论】:

  • 这绝对有道理。但是因为我使用的是 DustJS,所以这对我不起作用:/ .. 我做 this.$el.html(this.template(this.model.toJSON())); 父视图不显示最新的模型更改。 html 不显示模型更改。
【解决方案2】:

尝试使用成功回调,让我知道我认为您的问题可能来自这里:

this.model.save({att1: "value"}, {success:handler1, error: handler2});

您还确定要使用 listenToOnce 吗?而不是 listenTo ??

【讨论】:

  • 不,这不起作用。我的函数看起来像这样this.responseMessageView.model.save({data: {email: emailAddress.val()}}); ..另外我必须提到成功回调肯定会被触发。因为我有控制台语句。
  • 我试过这个this.responseMessageView.model.save({data: {email: emailAddress.val()}}, {success :this.responseViewSuccess, error: this.responseViewError}); ..这不起作用:(我错过了什么?
  • 我听了但仍然无济于事:/
【解决方案3】:

在渲染后尝试this.delegateEvents() (http://backbonejs.org/#View-delegateEvents)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多