我正在尝试修改Todos示例以更好地理解框架。
我正在尝试修改todosController以添加一个'completed'计算属性,该属性返回所有已完成的待办事项。最重要的是,我正在尝试更新'areAllCompleted'属性。
我有这段代码,当'completed'发生变化时,它不会更新'areAllCompleted'。
TodosThree.todosController = SC.ArrayController.create({
completed: function(){
if(this.get('content')){
return this.get('content').find(
SC.Query.local(
TodosThree.Todo,
'isCompleted = true'
)
);
}
else {
return [];
}
}.property('content').cacheable(),
areAllCompleted: function (k, v) {
console.log('get');
if (v !== undefined) {
this.setEach('isCompleted', v);
}
return this.getPath('completed.length') === this.get('length');
# This .property definition doesn't work with .*completed.length .. ?
}.property('length','.*completed.length')
});
但是,如果我稍微更改代码以添加绑定,则可以正常工作:
TodosThree.todosController = SC.ArrayController.create({
completed: function(){
if(this.get('content')){
return this.get('content').find(
SC.Query.local(
TodosThree.Todo,
'isCompleted = true'
)
);
}
else {
return [];
}
}.property('content').cacheable(),
# For some reason, this binding works ...
completedLengthBinding: SC.Binding.oneWay('.*completed.length'),
areAllCompleted: function (k, v) {
console.log('get');
if (v !== undefined) {
this.setEach('isCompleted', v);
}
return this.getPath('completed.length') === this.get('length');
# If I reference the binding that references completed, this now works ...
}.property('length','completedLength')
});
为什么这种微妙的差异会突然变得有效?
感谢。
答案 0 :(得分:1)
当您使用.property()
方法时,参数应该是对象的直接属性;因此,它不会扩展您传递的属性路径(.*completed.length
)。当您设置绑定时,您基本上告诉SproutCore您希望路径(.*completed.length
)绑定到对象的属性,这就是第二个工作的原因;因为它已成为一个简单的财产。
由于您是根据完成情况设置这两个方法,因此您可以采用的另一种方法是使用.observes()
的单个函数 跟随属性路径,但是有点复杂。以下是我可能会如何处理这个问题:
/*
* Note that using a store.find will auto-update when new todos are pushed
* into the store, so there is no need to reset this every time.
*/
completed: TodosThree.store.find(
SC.Query.local('TodosThree.Todo', 'isCompleted = true')
),
/*
* Go ahead and grab the length so we can use it as a dependent property below
*/
completedLengthBinding: '*completed.length',
/*
* Create the property function
*/
allAreCompleted: function(key, value) {
if (value !== undefined) {
this.setEach('isCompleted', value);
}
return this.everyProperty('isCompleted');
}.property('completed', 'completedLength')
有几点需要注意:由于您想要致电allAreCompleted()
并传递一个值,因此 DO 希望将其作为属性,而不仅仅是观察者。从技术上讲,你可以使用一个既作为观察者又作为属性更新程序的函数,但我认为这更清楚。
另外,请注意使用everyProperty()
方法,该方法将遍历每个待办事项并确保所有待办事项的传递属性为true。
希望这有帮助!请询问您是否需要澄清:-D