如何在emberjs中的视图之间转换时处理取消/回滚

时间:2013-04-16 13:49:21

标签: javascript ember.js ember-data

所以我回答了similar question一段时间。然而,关于这个解决方案的一些事情留下了难闻的气味。

这是一个场景,当我想创建一条记录时,我有一条新路线。例如PostsNewRoute,例如:

App.PostsNewRoute = Ember.Route.extend({
  model: function() {
    return App.Post.createRecord({title: '', content: ''});
  },
  deactivate: function() {
    var controller = this.controllerFor('posts.new');
    var content = controller.get('content');
    if (content && content.get('isNew') && !content.get('isSaving')) {
      content.deleteRecord();
    }
  }
});

,同样适用于PostsEditRoute

App.PostsEditRoute = Ember.Route.extend({
  model: function(params) {
    return App.Post.find(params.post_id);
  },
  deactivate: function() {
    var controller = this.controllerFor('posts.edit');
    var content = controller.get('content');
    if (content && content.get('isDirty') && !content.get('isSaving')) {
      content.rollback();
    }
  }
});

这对我来说似乎不对。我觉得有太多的代码来处理这个问题,并且在一个更大的应用程序中,我正在为许多对象执行此操作...

所以这是我尝试过的一种不同的方法,看起来有点干净,但是它有自己的问题(参见跳转后):

App.PostsNewRoute = Ember.Route.extend({
  model: function() {
    return App.Post.createRecord({title: '', content: ''});
  }
});

App.PostsEditRoute = Ember.Route.extend({
  model: function(params) {
    return App.Post.find(params.post_id);
  }
});

App.PostsFormView = Ember.View.extend({
  templateName: 'posts/form',
  tagName: 'form',
  classNames: ['form-horizontal'],

  buttonText: '',

  submit: function() {
    // TODO: validation
    this.get('controller').get('store').commit();
    this.get('controller').transitionToRoute('posts.index');
  },

  cancel: function() {
    var content = this.get('controller').get('content');
    if(content && !content.get('isSaving')) {
      if(content.get('isNew')) {
        content.destroyRecord();
      } else if(content.get('isDirty')) {
        content.rollback();
      }
    }
    this.get('controller').transitionToRoute('posts.index');
  }
});

模板:

<div class="control-group">
  <label class="control-label">Title:</label>
  <div class="controls">
    {{view Ember.TextField valueBinding='title'}}
  </div>
</div>
<div class="control-group">
  <label class="control-label">Content:</label>
  <div class="controls">
    {{view Ember.TextArea valueBinding='content'}}
  </div>
</div>
<div class="form-actions">
  <button class="btn btn-primary">{{view.buttonText}}</button>
  <a href="#" class="btn btn-danger" {{action cancel target='view'}}>Cancel</a>
</div>

这与我之前尝试的几乎相同,但是,现在如果用户点击导航链接或点击后退按钮,则不会清理。

这两种方式似乎都不对,处理这种方式的正确或更好的方法是什么?

1 个答案:

答案 0 :(得分:2)

好吧,我喜欢我在this nice little gist找到的东西(有趣的部分接近底部)。

在该示例之后,PostsNewController的(部分)如下所示:

startEditing: function() {
    this.transaction = this.get('store').transaction();
    this.set('content', this.transaction.createRecord(EmberBlog.Post, {}));
},

stopEditing: function() {
    if (this.transaction) {
        this.transaction.rollback();
        this.transaction = null;
    }
}

和我的PostsNewRoute是这样的:

EmberBlog.PostsNewRoute = Ember.Route.extend({
  model: function() {
    return null;
  },

  setupController: function(controller) {
    controller.startEditing();
  },

  deactivate: function() {
    this.controllerFor('posts.new').stopEditing();
  }
});

我认为应该很容易适应您的特定需求。