5

我有一个 Ember 列表和一个编辑表单。每次列表中选定的项目更改时,编辑表单都会丢弃任何更改并加载新模型。

我的问题是无法丢弃更改,因为停用事件不会触发。

例如,从url/favs/123/editurl/favs/456/edit停用(和退出)事件不会触发。因此,无法正确丢弃任何更改。

这是我所指的代码的一部分:

App.Router.map(function() {
    this.resource('favs', { path: '/favs' }, function() {
        this.route('new');
        this.route('edit', { path: ':fav_id/edit' })
    });
});

[...]

App.FavsEditRoute = Ember.Route.extend({
    deactivate: function() {
        var model = this.get('currentModel');
        if(model && model.get('isDirty')) {
            model.get('transaction').rollback();
        }
    },

    model: function(params) {
        return App.Fav.find(params.fav_id);
    },
});
4

3 回答 3

4

我建议使用 willTransition 路由操作。它目前似乎被宣传为 Ember 指南中的解决方案:

https://guides.emberjs.com/release/routing/preventing-and-retrying-transitions/

除了在公共 API 中,这种方法的优点是您可以提示用户确认他们是否真的要放弃更改,如果他们拒绝,则取消转换。

例如:

App.FavsEditRoute = Ember.Route.extend({
  ...
  actions: {
    willTransition: function(transition) {
      controller = this.controllerFor('fav');
      if (controller.get('isDirty') &&
          !confirm("Are you sure you want to abandon progress?")) {
        transition.abort();
        return false;
      } else {
        controller.get("content").rollback();
        return true;
      }
    }
  }
});
于 2013-10-04T18:31:58.000 回答
2

当路由完全离开时,才执行 deactivate 钩子。因此,我建议覆盖您的路线的 contextDidChange 函数。以下是 Ember Source 的摘录:

Ember.Route = Ember.Object.extend({
    /**
    @private

    Called when the context is changed by router.js.
  */
  contextDidChange: function() {
    this.currentModel = this.context;
  }
});

我建议这样做:

App.FavsEditRoute = Ember.Route.extend({
    deactivate: function() {
        this.doRollback();
    },
    contextDidChange: function() {
        this.doRollback();
        this._super();
    },
    doRollback: function(){
        var model = this.get('currentModel');
        if(model && model.get('isDirty')) {
            model.get('transaction').rollback();
        }
    }
});
于 2013-03-24T11:39:39.163 回答
1

在 Ember 2.2 中,正确的代码(在路由中)是:

actions: {
  saveScene: function (scene) {
    var _that = this;

    scene.save().then(function (response) {
      // on saveScene action, go to list route
      _that.transitionTo('scenes');
    });
  },

  willTransition: function (transition) {
    // on transition, if model has unsaved changes, revert them
    var model = this.controller.get('model');
    if (model && model.get('hasDirtyAttributes')) {
      model.rollbackAttributes();
    }
  }
}
于 2015-12-18T08:43:55.737 回答