简体   繁体   English

Backbone局部视图无法渲染最新模型

[英]Backbone partial view not rendering the latest model

I am relatively new to Backbone and I am running into this problem. 我对Backbone相对较新,我遇到了这个问题。

I am using Backbone with DustJS 我正在使用Backbone和DustJS

My template looks something like this - index.dust 我的模板看起来像这样 - index.dust

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

This is my partial below - responseMessage.dust 这是我的部分 - responseMessage.dust

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

My JS looks like this 我的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
},

Below function is called when an event occurs and it does a POST and returns successfully. 当事件发生时调用下面的函数,它执行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
}

My implementations of the callback function 我的回调函数的实现

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

this.model belongs to the model of the whole page. this.model属于整个页面的模型。 Whereas this.responseMessageView.model is the model for the partial. this.responseMessageView.model是partial的模型。

Question: This works perfectly fine in most of the cases. 问题:在大多数情况下,这种方法完全正常。 There is one case where it does not render the partial with the latest model values. 有一种情况是它不会使用最新的模型值渲染部分。 When I click on the button on index.dust and primaryViewSuccess is executed. 当我点击index.dust上的按钮并执行primaryViewSuccess After which I click on another button and trigger responseViewEventTrigger . 之后我点击另一个按钮并触发responseViewEventTrigger It does the POST successfully and it comes to responseViewSuccess and stores it in the model too. 它成功完成POST,它来自responseViewSuccess并将其存储在模型中。 But it does not show it on the frontend. 但它没有在前端显示出来。 data.success is still not true whereas console.log(this.responseMessageView.model) show that attributes->data->success = true data.success仍然不正确,而console.log(this.responseMessageView.model)显示attributes->data->success = true

But the same behavior when I refresh the page it all works perfect. 但是当我刷新页面时它的行为完全相同。 Its just that when primaryViewSuccess is called and then responseViewSuccess its not taking the latest model changes. 它只是在primaryViewSuccess然后responseViewSuccess它没有采取最新的模型更改。 In other words model is being updated but the DOM remains the same. 换句话说,模型正在更新,但DOM保持不变。

What am I missing here? 我在这里错过了什么? Thanks for your time! 谢谢你的时间!

You're hitting the classic Backbone render-with-subviews gotcha: When you render the index view, you are replacing all of the DOM nodes. 您正在使用经典的Backbone render-with-subviews gotcha:当您渲染索引视图时,您将替换所有 DOM节点。 That includes the DOM node that your responseMessageView instance is tied to. 这包括您的responseMessageView实例绑定的DOM节点。 If you inspect the responseMessageView.el you'll actually see that it has been updated with the new model data, however the element isn't attached to the index's DOM tree anymore. 如果检查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);
  }
});

Here when you manually call render, child.el will no longer be in the parent.el (you can check using the inspector). 在这里手动调用render时, child.el将不再位于parent.el (您可以使用检查器进行检查)。

The simplest fix here is to call child.setElement after the parent renders with the newly rendered div#responseMessage element. 这里最简单的解决方法是在父渲染后使用新渲染的div#responseMessage元素调用child.setElement The better fix is to detach the responseMessageView 's element beforehand, and reattach after: 更好的解决方法是预先分离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);
  }
});

Try to use success callback and let me know I think your problem may come from here: 尝试使用成功回调,让我知道我认为你的问题可能来自这里:

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

Also are you sure you want to use listenToOnce ? 你还确定要使用listenToOnce吗? instead of listenTo ?? 而不是listenTo ??

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM