1

我想为 Dojo 商店运行一些特定put()的代码。add()我遇到的问题是,对于 JSON REST 存储,在 JsonRest.jsadd()中只是一个调用的函数put()

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

因此,如果我使用aspect.around()with add()如果我将代码应用到使用实现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);
  });

我的问题是:是否有一种简单的“短”方法来更改我现有的代码,以便它检查它是否在一个方法内,并避免运行代码两次?

我试了一下,但我最终得到了叮当、笨拙的代码。我确定我错过了一些东西......

这是我现有的代码:

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()连续调用两次,是否有可能被第一次调用inMethod设置为true,然后第二次add()调用发现它已经设置为 true,因为第一个调用还没有设法将其设置为 false?

nextTick()如果在我假设的两个调用之间调用,这真的可能吗?

还是我完全被这一切弄糊涂了?(这很有可能......)

  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 回答