EmberJS: bootstrap modal refuses to re-open due to record not being correctly deleted?

被刻印的时光 ゝ 提交于 2019-12-11 20:47:15

问题


The Goal:

The thing that I am really trying to accomplish here is gain an understanding how to work with model records cleanly. In this particular case, these records are kind of "one-offs". If the modal is closed without saving, then they are meant to be cleared from memory... and once a record is saved to the server there is also no need to keep the re record stored client side.

Description:

I created a button action that transitions into a "payment" route, which renders inside a Bootstrap modal.

This route creates a "payment" record and also pulls a list of available "debts" the payment can be applied to.

App.PaymentRoute = Ember.Route.extend({
  model: function() {
    console.log('( Router: Model Hook )--------------------)');
    return this.store.createRecord('payment');
  },
  afterModel: function() {
    console.log('( Router: AfterModel Hook )--------------------)');
    var route = this;
    return Ember.RSVP.hash({
      debt_list: this.store.find('debt', { account_id: 36, page_size: 100, page_number: 1 })
    }).then(function(hash) {
      route.setProperties({
        account_id: 36,
        debt_list: hash.debt_list
      });
    });
  },
  setupController: function(controller, model) {
    console.log('( Router: SetupController Hook )--------------------)');
    this._super(controller, model);
    controller.setProperties({
      account_id: this.get('account_id'),
      debt_list: this.get('debt_list')
    });
  },
});

Closing the modal should delete the current record and transition back to index...

actions: {
    removeModal: function() {
      this.currentModel.deleteRecord();
      this.transitionTo('index');
      return true;
    }
  }

when payment button is clicked a second time, it "should" create a new payment record... but instead an error occurs, because the previous record has not been correctly cleared?

I successfully recreated the issue in this JSBin

Am i not creating and deleting records correctly?

Side Note:

I have set console.log() on all my route and controller methods... I noticed that setupController does not fire on the second open attempt.... also my controller cp's and observers are triggering multiple times during the initialization proces... i dont know if that is contributing to the problem or not?


回答1:


I don't think you actually want to 'delete' the record. What you want to do is rollback any changes to it and then unload it. I would do this in your willTransition hook on the route so no-matter how you leave the route, the model will be unloaded.

Code:

willTransition: function(transition) {
  var model = this.currentModel;
  var debt_list = get(this, 'debt_list');
  var store = this.store;

  // dispose of models after views have been finalised 
  Ember.run.once(function() {
    if (model) {
      model.rollback();
      store.unloadRecord(model);
    }
    if (debt_list) {
      debt_list.forEach(function(debt) {
        debt.rollback();
        store.unloadRecord(debt);
      });
    }
  }
}

UPDATE: It is important to unload records from the ember run-loop to give any views bound to those records a chance to be torn down before ripping models out from under them. That is why the model disposing is performed within Ember.run.once().

Another observation is that you should be able kick off the debt_list request in your model hook using RSVP.hash. So putting it all together your route should look something like the following:

var get = Ember.get, set = Ember.set;

App.PaymentRoute = Ember.Route.extend({
  model: function(params, transition, queryParams) {
    return Ember.RSVP.hash({
      content: this.store.createRecord('payment'),
      debt_list: this.store.find('debt', { account_id: 36, page_size: 100, page_number: 1 })
    });
  },

  setupController: function(controller, hash) {
    if (controller && hash) {
      controller.setProperties(hash);
      set(controller, 'account_id', 36);
    }
  },

  actions: {

    willTransition: function(transition) {
      var hash = this.currentModel;
      var store = this.store;

      // tell controller to reset/cleanup - you should set any
      // model related properties ie 'content'/'model' and 'debt_list'
      // to null/default values.
      this.controller.reset();

      if (hash) 
        // dispose of models after views have been finalised 
        Ember.run.once(function() {
          hash.content.rollback();
          store.unloadRecord(hash.content);
          hash.debt_list.forEach(function(debt) {
            debt.rollback();
            store.unloadRecord(debt);
          });
        });
      }
    }
  }
});

I have updated your JSBin here so its working perfectly, models are correctly removed from the store.




回答2:


The problem seems to be the this.store.find('debt', { account_id: 36, page_size: 100, page_number: 1 })

Because ember data will load the items into the store once the query finishes, and the controller is bound to that array, when it changes all observers are fired.

so setDebtPayments is getting called, (before setupController), trying to do model.set('payment_debts', paymentDebts); which at that point is already destroyed.

I managed to fix this (suboptimaly) by creating a new payment record when removeModal is called.

Another option, is to check if there is a model decorated by the controller, before doing anything with it: http://jsbin.com/ziket/8



来源:https://stackoverflow.com/questions/26552159/emberjs-bootstrap-modal-refuses-to-re-open-due-to-record-not-being-correctly-de

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!