2014-09-10 43 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在給應用程序做錯誤的事情時感到刺痛。您可能不需要爲每個待辦事項對象都有一個後備控制器,您只需要待辦事項對象本身。