灰烬数据固定装置并查看绑定.是这些错误



我正在尝试实现由待办事项组成的待办事项列表,其中包含多个条目视图的嵌套条目视图。每个条目都有删除的能力,因此可以从容器视图中删除。

当连接到我的Rails应用程序时,此几乎可以工作。单击删除按钮(或app.todoentry.find(x).deleterecord()在控制台中触发)实例设置为isDirty = true,但在视图中仍然可见。

要尝试测试发生的事情,我使用固定装置进行了单独的JSFIDDLE,以查看是否可以孤立地工作,然后我想我可能还偶然发现了Ember Data中使用固定装置的错误。

首先,这是我一直在研究的Rails Ember应用:

Rails

class ToDo < ActiveRecord::Base
  has_many :to_do_entries, dependent: :destroy  
  attr_accessible :is_deleted, :is_staging, :is_template, :title
  validates_presence_of :title
end
class ToDoSerializer < ActiveModel::Serializer
  attributes :id,
             :title
  has_many :to_do_entries, embed: :objects
end
class ToDoEntry < ActiveRecord::Base  
  belongs_to :to_do
  attr_accessible :completed_at, :is_deleted, :priority, :title
  validates_presence_of :to_do, :title
end
class ToDoEntrySerializer < ActiveModel::Serializer
  attributes :id,
             :to_do_id,
             :title,
             :priority
end

ember

/*---------------*/
/* Application   */
/*---------------*/
PLURAL_MAPPINGS = {"to_do_entry": "to_do_entries"};
App = Em.Application.create({
  rootElement: '#content',
  store: DS.Store.create({
    adapter:  DS.RESTAdapter.create({ plurals: PLURAL_MAPPINGS }),
    revision: 4
  })
});
/*---------------*/
/* Controllers   */
/*---------------*/
App.TodoController = Ember.ObjectController.extend({
  destroy: function() {
    this.transaction = App.store.transaction();
    this.transaction.add(this.get('content'));
    if (window.confirm("Are you sure you want to delete?")) { 
      this.get('content').deleteRecord();
      this.transaction.commit();
      App.router.transitionTo('todo');
    }
    else{
      this.transaction.rollback();
      this.transaction = null;
    }
  }
});
App.Todo_entriesController = Ember.ArrayController.extend();
App.Todo_entryController = Ember.ObjectController.extend({
  destroy: function() {
    this.transaction = App.store.transaction();
    this.transaction.add(this.get('content'));
    if (window.confirm("Are you sure you want to delete?")) { 
      this.get('content').deleteRecord();
      this.transaction.commit();
      App.router.transitionTo('todo');
    }
    else{
      this.transaction.rollback();
      this.transaction = null;
    }
  }
});
/*--------*/
/* Models */
/*--------*/
App.ToDo = DS.Model.extend({
  title: DS.attr('string'),
  group: DS.belongsTo('App.Group'),
  to_do_entries: DS.hasMany('App.ToDoEntry', { embedded: true })
});
App.ToDoEntry = DS.Model.extend({
  title: DS.attr('string'),
  to_do_id: DS.attr('number'),
  priority: DS.attr('number'),
  todo: DS.belongsTo('App.ToDo')
});
/*-------*/
/* Views */
/*-------*/ 
App.TodoView = Ember.View.extend({
  templateName: 'app/templates/todo'
});
App.Todo_entriesView = Ember.View.extend({
  templateName: 'app/templates/todo_entries'
});
App.Todo_entryView = Ember.View.extend({
  templateName: 'app/templates/todo_entry',
  destroyEntry: function() {
    console.log('Todo_entryView - destroyEntry');
    this.get('controller').destroy();
  },
  init: function(){
    this._super();
    this.set(
      'controller',
      App.Todo_entryController.create({ content: this.get('content') })
    );
  }  
});  
/*-----------*/
/* Templates */
/*-----------*/ 
todo.hbs
<article>
  <h1>{{title}}</h1>  
  <div class="widget_links">
    <a {{action destroy target="view"}}>Delete</a>
  </div>
  {{outlet}}
</article>
todo_entries.hbs
{{#if isLoading}}
  <p>Loading...</p>
{{else}}
  <ul class="list">
  {{collection contentBinding="content" itemViewClass="App.Todo_entryView"}}
  </ul>
{{/if}}
todo_entry.hbs
<li>
{{#if isLoading}}
  Loading...
{{else}}
  {{view.content.id}}) {{view.content.title}} Priority: {{view.content.priority}}
  <a {{action destroyEntry href="true" target="view"}}>Delete</a>
{{/if}}
</li>
/*--------*/
/* Router */
/*--------*/
App.Router = Ember.Router.extend({
  enableLogging: true,
  location: 'hash',
  root: Ember.Route.extend({
    index: Ember.Route.extend({
      route: '/',
      connectOutlets: function(router) {
        var todo = App.ToDo.find(21);
        router.get('applicationController').connectOutlet('todo', todo);
        var todoController = router.get('todoController');
        todoController.connectOutlet('todo_entries', todoController.get("to_do_entries"));
      }
    })
  })
}); 
App.initialize();

如上所述,这非常接近工作,但令人沮丧的是,似乎并没有从视图中删除该条目。我在这里做些明显的错误,还是这是一个错误?

带固定装置的错误?

其次,我制作了一个使用固定装置的版本。但是,除非请求app.todo.find()(即findall),否则固定数据似乎不会加载。

这是两个示例:

单身,失败删除。

http://jsfiddle.net/danielrosewarne/vdghe/1/

第一个加载单个要做的,其中是关联的条目。当您单击"删除"时,您会正确获取警告,并使对象无效。但是,该条目仍留在视图中。

注意,如果您在上面使用控制台查看

多倍到dos,一切都可以

http://jsfiddle.net/danielrosewarne/lelyy/1/

第二个列表在索引视图中列出了所有执行记录,从而预先加载数据。当您单击"要执行"以查看其条目时,删除作品如您所期望的。(顺便说一句,如果您在示例1中的控制台中只做app.todo.find(),这也有效。)

对我来说,这就像是灰数据中的错误,我是对的还是我做错了什么?

谢谢,

dan

transaction.commit()是异步的,但是您立即过渡到路由中的另一个状态。在交易完成之前,该视图正在更新。我相信这是问题,或者至少这是一个问题。在异步操作方面,Ember非常棘手。尝试以下操作:

App.Todo_entryController = Ember.ObjectController.extend({
  destroy: function() {
    this.transaction = App.store.transaction();
    this.transaction.add(this.get('content'));
    if (window.confirm("Are you sure you want to delete?")) { 
      this.get('content').deleteRecord();
      this.get('content').one('didDelete', function() {
        App.router.transitionTo('todo');
      });
      this.transaction.commit();
    }
    else{
      this.transaction.rollback();
      this.transaction.delete();
    }
  }
});

此外,整个函数应该在路由器中,而不是控制器中,因为它会改变状态。当您将状态粘贴在路由器中时,您正在掩埋状态。

欢呼。

最新更新