1
votes

I have an ember app with a data model and the usual CRUD views/routes/controllers for listing and adding new items.

When I click 'add new' from the index page, I get the expected form, with 'Save' and 'Cancel' buttons. If I press cancel, the view goes back to the index view and the model is not saved, as expected.

This is the code of the new items controller:

App.ItemsNewController = Ember.ObjectController.extend({
  actions: {
    saveChanges: function() {
      this.model.save();
      this.transitionTo('items');
    },
    cancel: function() {
      this.model.rollback(); // how to run this when the back button is pressed?
      this.transitionTo('items');
    },
  },
});

But if I press the back button, I also end up in the index page, but an extra empty row appears in the index listing, corresponding to the new record that was not saved in the 'new' view. This record was not persisted to the data layer, but it somehow still exists in memory, and this.store.find('items') returns a collection that includes it. If I refresh the page, the blank row disappears. Also, as stated above, if I exit the form using the cancel button, the record is discarded, because in the 'cancel' action method I invoke this.model.rollback().

So bottomline, I guess I would have to rollback the model when the back button is pressed, but there's no route callback that I know of to hook some code to this event.

In case it's important, I'm using Ember 1.9.1, Ember Data 1.0.0-beta.15-canary, Handlebars 2.0.0, jQuery 1.10.2

1

1 Answers

4
votes

Well, this is the second time in a row that I post to stackoverflow and I find the answer shortly after, so I guess I should refrain from asking here unless I'm literally clueless and hopeless ;)

Thanks to this other question, I found out that there is an exit event on the route. So the key to solve this is on the route, and not in the controller. I ended up putting the model rollback in the route's exit event method, as shown below:

UPDATE: @NicholasJohn16 points out that it is better to use the deactivate hook, instead of exit. See the details in the comments below. The code example has been changed accordingly.

App.ItemsNewRoute = Ember.Route.extend({
  model: function() {
    return this.store.createRecord('item', {
      title: 'Untitled',
      status: 'new',
    });
  },
  deactivate: function() {
    model = this.controllerFor('notifications.new').get('model');
    model.rollback();
  },
});

Once this is done, you can even remove the model.rollback() call from the cancel action in the controller, and leave just the transitionTo('items') call. Since the route's deactivate event will always be called, regardless of the way you leave the view, the model will always be discarded.