Частичный вид базовой линии не отображает последнюю модель

Я относительно новичок в Backbone, и я сталкиваюсь с этой проблемой.

Я использую Backbone с DustJS

Мой шаблон выглядит примерно так: 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->data->success = true

Но такое же поведение, когда я обновляю страницу, все работает отлично. Это просто, когда вызывается primaryViewSuccess, а затем responseViewSuccess не принимает последние изменения модели. Другими словами, модель обновляется, но DOM остается прежней.

Что мне здесь не хватает? Спасибо за ваше время!

Ответ 1

Вы попадаете в классический рендеринг с поддержкой подкласса Backbone. Если вы визуализируете индексный вид, вы заменяете все узлы DOM. Это включает DOM node, к которому привязан ваш экземпляр responseMessageView. Если вы проверите 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);
  }
});

Здесь, когда вы вручную вызываете рендер, child.el больше не будет в parent.el (вы можете проверить с помощью инспектора).

Самое простое исправить здесь - вызвать child.setElement после того, как родительский рендеринг с новым визуализированным элементом div#responseMessage. Лучшее исправление состоит в том, чтобы предварительно отсоединить элемент 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);
  }
});

Ответ 2

Попробуйте использовать обратный вызов и дайте мне знать. Я думаю, что ваша проблема может возникнуть здесь:

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

Также вы уверены, что хотите использовать listenToOnce? вместо прослушивания.