0

フレームワークをよりよく理解するために、Todosの例を変更しようとしています。

todosControllerを変更して、完了したすべてのTodoを返す「完了した」計算プロパティを追加しようとしています。これに加えて、「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')
});

この微妙な違いが突然機能するのはなぜですか?

ありがとう。

4

1 に答える 1

1

メソッドを使用している場合.property()、パラメーターはオブジェクトの直接のプロパティであることが期待されます。そのため、渡すプロパティ パス ( .*completed.length) には展開されません。.*completed.lengthバインディングを設定するとき、基本的には、パス ( ) をオブジェクトのプロパティにバインドすることを SproutCore に伝えます。これが、2 番目のプロパティが機能する理由です。単純なプロパティになっているためです。

補完に基づいてこれらの両方を設定しているため、別の方法として、プロパティ パスをたどる単一の関数を使用することもできますが、.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()渡したいので、これを単なるオブザーバーではなくプロパティとして使用する必要があります。技術的には、オブザーバーとプロパティ アップデーターの両方として機能する関数を使用してそれを行うこともできますが、これはより明確だと思います。

everyProperty()また、各 todo を反復処理し、渡されたプロパティがすべての todo に対して true であることを確認するメソッドの使用にも注意してください。

お役に立てれば!何か説明が必要な場合はお尋ねください:-D

于 2012-08-20T21:51:49.300 に答える