1

put()私は、Dojo ストアの周辺およびDojo ストアに対して、いくつかの特定のコードを実行したいと考えていますadd()。私が抱えている問題は、JSON REST ストアの場合、JsonRest.jsadd()は次を呼び出す関数にすぎないことですput()

add: function(object, options){
  options = options || {};
  options.overwrite = false;
  return this.put(object, options);
},

aspect.around()そのため、 withを使用すると、へのスタブとして実装するストアで作成されたストアにコードを適用すると、コードが2add()回実行されることになります。add()put()

ほとんどの店がそうしていることを私は認識していることに注意してください. メソッドのネストがあるかどうかに関係なく、ソリューションがどのストアでも動作することが保証されるようにしたいだけです。

Dojo 自身Observable.jsも同じ問題を抱えています。これは彼らがそれに対処する方法です:

function whenFinished(method, action){
    var original = store[method];
    if(original){
      store[method] = function(value){
        if(inMethod){
          // if one method calls another (like add() calling put()) we don't want two events
          return original.apply(this, arguments);
        }
        inMethod = true;
        try{
          var results = original.apply(this, arguments);
          Deferred.when(results, function(results){
            action((typeof results == "object" && results) || value);
          });
          return results;
        }finally{
          inMethod = false;
        }
      };
    }
  }
  // monitor for updates by listening to these methods
  whenFinished("put", function(object){
    store.notify(object, store.getIdentity(object));
  });


  whenFinished("add", function(object){
    store.notify(object);
  });
  whenFinished("remove", function(id){
    store.notify(undefined, id);
  });

私の質問は次のとおりです。既存のコードを変更して、メソッド内にあるかどうかを確認し、コードを 2 回実行しないようにする簡単な「短い」方法はありますか?

私はそれを試してみましたが、厄介でハッキーなコードになってしまいました. 私は何かが欠けていると確信しています...

これが私の既存のコードです:

topic.subscribe( 'hotplate/hotDojoStores/newStore', function( storeName, store ){

  aspect.around( store, 'put', function( put ){

    return function( object, options ){

      return when( put.call( store, object, options ) ).then( function( r ) {
        var eventName;
        var identity = store.idProperty;
        eventName = object[ identity ] ? 'storeRecordUpdate' : 'storeRecordCreate';

        topic.publish( eventName, null, { type: eventName, storeName: storeName, objectId: r[ identity ], object: object }, false );

      } );

    }
  });

  aspect.around( store, 'add', function( add ){
    return function( object, options ){

      return when( add.call( store, object, options ) ).then( function( r ) {

        var identity = store.idProperty;

        topic.publish('storeRecordCreate', null, { storeName: storeName, storeTarget: storeTarget, objectId: r[identity], object: object }, false }  );

      });
    }
  });
});
4

1 に答える 1

0

これは私の試みです... 私の試みについて実際に「理解」できないのは、それが 100% 安全かどうかです。

store.add()が連続して 2 回呼び出された場合、最初の呼び出しでにinMethod設定さtrueれ、最初の呼び出しがadd()まだ false に設定されていないため、2 番目の呼び出しで既に true に設定されていることが判明する可能性はありますか?

これはnextTick()、私が想定している 2 つの呼び出しの間に呼び出された場合にのみ可能でしょうか?

それとも、私は完全に混乱していますか?(これは非常に可能性があります...)

  topic.subscribe( 'hotplate/hotDojoStores/newStore', function( storeName, store ){

    var inMethod;

    aspect.around( store, 'put', function( put ){

      return function( object, options ){

        if( inMethod ){
          return when( put.call( store, object, options ) );
        } else {

          inMethod = true;

          try {
            return when( put.call( store, object, options ) ).then( function( r ) {
              var eventName;
              var identity = store.idProperty;
              eventName = object[ identity ] ? 'storeRecordUpdate' : 'storeRecordCreate';

              topic.publish( eventName, null, { type: eventName, storeName: storeName, objectId: r[ identity ], object: object }, false );

            });
          } finally {
            inMethod = false;
          }

        }

      }
    });

    aspect.around( store, 'add', function( add ){
      return function( object, options ){

        if( inMethod ){
          return when( add.call( store, object, options ) );
        } else {

          inMethod = true;

          try {

            return when( add.call( store, object, options ) ).then( function( r ) {

              var identity = store.idProperty;

              topic.publish('storeRecordCreate', null, { type: 'storeRecordCreate', storeName: storeName, objectId: r[identity], object: object }, false );

            });
          } finally {
            inMethod = false;
          }
        }
      }

    });

    aspect.around( store, 'remove', function( remove ){
      return function( objectId, options ){

        return when( remove.call( store, objectId, options ) ).then( function( r ) {

          topic.publish('storeRecordRemove', null, { type: 'storeRecordRemove', storeName: storeName, objectId: objectId }, false );

        });
      };
    });

  });
于 2013-12-23T06:42:11.957 に答える