2014-09-10 39 views
0

观察变化的ItemController我一直在EmberCli重新创建TodoMVC学习余烬。我重新创建了所有的功能,但是我遇到了一个问题,我希望有人能够对这种情况有所了解。在阵列控制器

看来,我的托多斯ArrayController将观察和消防功能,当在我的模型的变化属性,但不是当我的待办事项ObjectController变化值。

我搬到isEditing模型,以便当我打电话editTodocanToggle火灾。但我宁愿将该值存储在我的控制器中,而不是模型中。

我建立了一个测试用一个propTest布尔值。点击一个按钮我火propToggletodoPropToggle未对变化做出反应。它唯一启动的时间是初始化。

任何洞察将是超级有用。

TODOS控制器

import Ember from 'ember'; 
export default Ember.ArrayController.extend({ 
actions: { 
    createTodo: function() { 
    var title = this.get('newTitle'); 
    if (!title.trim()) { 
     return; 
    } 
    var todo = this.store.createRecord('todo', { 
     title: title, 
     isCompleted: false, 
     isEditing:false 
    }); 

    this.set('newTitle', ''); 
    todo.save(); 
    } 
    }, 

    canToggle: function() { 
    var isEditing = this.isAny('isEditing'); 
    return this.get('length') && !isEditing; 
    }.property('length','@each.isEditing'), 

    todoPropToggle: function() { 
    var hasPropTest = this.isAny('propTest'); 
    return hasPropTest; 
    }.property('@each.propTest') 
}); 

TODO控制器

import Ember from 'ember'; 

export default Ember.ObjectController.extend({ 

    actions: { 
    editTodo: function() { 
     var todo = this.get('model'); 
     todo.set('isEditing', true); 
    }, 

    removeTodo: function() { 
     var todo = this.get('model'); 
     todo.deleteRecord(); 
     todo.save(); 
    }, 

    acceptChanges: function() { 
     var todo = this.get('model'); 
     todo.set('isEditing', false); 
     if (Ember.isEmpty(this.get('model.title'))) { 
     this.send('removeTodo'); 
     } 
     else { 
     this.get('model').save(); 
     } 
    }, 

    propToggle:function(){ 
     this.set('propTest',!this.get('propTest')); 
    } 
    }, 

    propTest:true, 

    isCompleted: function(key, value) { 
    var model = this.get('model'); 
    if (value === undefined) { 
     return model.get('isCompleted'); 
    } 
    else { 
     model.set('isCompleted', value); 
     model.save(); 
     return value; 
    } 
    }.property('model.isCompleted') 
}); 

回答

1

怎么样的替代方法?我们可以通过使用parentController或指定需要直接从对象控制器切换arrayController中的'canToggle'。避免必须观察所有应该更高效的itemController。

TODOS控制器:

import Ember from 'ember'; 
export default 
Ember.ArrayController.extend({ 
    /** 
    * references the todo model that is currently being edited 
    */ 
    editingTodo: null, 
    canToggle: Ember.computed.notEmpty('editingTodo'), 

    actions: { 
     createTodo: function() { 
      var title = this.get('newTitle'); 
      if (!title.trim()) { 
       return; 
      } 
      var todo = this.store.createRecord('todo', { 
       title: title, 
       isCompleted: false, 
       isEditing: false 
      }); 

      this.set('newTitle', ''); 
      todo.save(); 
     } 
    } 
}); 

TODO控制器

import Ember from 'ember'; 

export default 
Ember.ObjectController.extend({ 

    needs:['todos'] 
    todos : Ember.computed.alias('controllers.todos'), 

    actions: { 
     editTodo: function() { 
      this.set('todos.editingTodo', this.get('model')); 
     }, 

     removeTodo: function() { 
      var todo = this.get('model'); 
      if (this.get('todos.editingTodo') === todo) { 
       this.set('todos.editingTodo', null); 
      } 
      todo.deleteRecord(); 
      todo.save(); 
     }, 

     acceptChanges: function() { 
      this.set('todos.editingTodo', null); 
      if (Ember.isEmpty(this.get('model.title'))) { 
       this.send('removeTodo'); 
      } 
      else { 
       this.get('model').save(); 
      } 
     } 
    }, 

    isCompleted: function (key, value) { 
     var model = this.get('model'); 
     if (value === undefined) { 
      return model.get('isCompleted'); 
     } 
     else { 
      model.set('isCompleted', value); 
      model.save(); 
      return value; 
     } 
    }.property('model.isCompleted') 
}); 

我没有测试过,但我希望你能我建议解决方案的JIST。

+0

这似乎工作,但这是真的结束了我想做的事情。这真的是这种功能的最佳做法吗?根据TodoMVC示例中的代码,我期待更清晰的方式。 – Caranicas 2014-09-10 21:30:28

+0

我想另一个可能更好的解决方案是基于路线的解决方案。所以在你的todo路径中,使用activate和deactivate钩子来设置todos控制器中的canToggle属性。 – 2014-09-10 22:16:35

+0

这是否意味着无法从数组控制器中观察对象控制器属性? – Caranicas 2014-09-10 22:18:47

1

propTest在这种情况下,这里看起来像是计算属性,而不是可观察值。 (编辑:不是那些计算属性没有底层可观察到的动力,但它们在使用上有所不同,因此我希望将它们分开)当底层propTest触发时它会触发,但如果没有变化,不运行在运行循环中。如果您希望这是一个原始的可观察对象,请使用observes()语法。 @each将在这里工作,但我喜欢显式,并有一个可观察的更新,而不是使用计算属性,除非需要直接访问该属性以在模板中绑定。

“仅在执行时触发”源自获取创建的计算属性的初始绑定。如果它在此之后从未触发,则用于计算属性@each.propTest的基础绑定必须是不正确的,否则确实会触发。

我想你也可能会混淆ObjectController的目的。一个Ember.Object可以完成一个控制器可以进行的所有可观察业务,但缺少支持它的“模型”或“内容”属性。看起来你可能想用一个直接的对象而不是这里的控制器来处理待办事项,因为实际上,实际上,实际上,实际上,“实际上”并不是一个“模型”类型。然后我将这些对象本身作为ArrayController内容的一部分,在这一点上,@each可以像你期望的那样迭代它们。

ObjectController与ArrayController的使用级别相同。你当然可以像在这里做的那样嵌套它们,但是我的spidey-sense在给应用程序做错误的事情时感到刺痛。您可能不需要为每个待办事项对象都有一个后备控制器,您只需要待办事项对象本身。