2015-01-16 45 views
0

我相信这与JS闭幕的方式工作,但我不完全确定。我正在使用AngularJS服务来管理在我的应用程序中使用的模型的生命周期。该服务使用fetch()save()的组合来运行GET和POST请求,从API获取和更新模型。在对象之后,我尝试将结果放入一个坐在服务中的对象中,以便稍后获取它。我的问题是,在成功save()后,我将结果放入同一个对象中,以便使用服务器上正确的对象来“更新”客户端上的对象(因此POST的结果是如果所有成功都只是有效载荷的回声)。对象没有正确更新内角服务

问题是我的对象不是持久的,并且所有后续调用save()都包含未完全更新的“陈旧”对象。

这里是我的服务:

app.factory('MailboxSubscription', function (API, $q, $stateParams, $rootScope) { 

    var Subscription = null; //THIS IS MODEL THAT I TRY TO UPDATE CONSTANTLY 
    var isBusy = false; 
    var service = {}; 
    var deferred; 

    var defaultFailure = function(res){ 

    } 

    service.fetch = function (success, force, failure) { 

     if(!failure){ failure = defaultFailure;} 


     if(isBusy){ 
      deferred.promise.then(success, failure); 
      return deferred.promise; 
     }else{ 
      deferred = $q.defer(); 
     } 

     if(Subscription && !force){ // ONCE THE MODEL HAS BEEN FETCHED ONCE, IT STAYS IN MEMORY AND ALL SUBSEQUENT CALLS WILL SKIP THE API CALL AND JUST RETURN THIS OBJECT 
      deferred.resolve(Subscription); 
     }else{ 
      //Make the API call to get the data 

      //Make the API call to get the data 
      if(typeof(success) === 'function'){ 
       var ServiceId = $stateParams.serviceId; 
      }else{ 
       var ServiceId = success; 
      } 

      isBusy = true; 
      API.Backups.O365.Exchange.get({id : ServiceId || $stateParams.serviceId}, function(res){ 
       isBusy = false; 
       if(res.success){ 
        Subscription = res.result; // ON A FIRST-TIME FETCH, THIS API CALL IS USED TO GET THE MODEL 
        deferred.resolve(Subscription); 
       }else{ 
        deferred.reject(res); 
       } 
      }, function(res){ 
       isBusy = false; 
       deferred.reject(res); 
      }); 
     } 

     deferred.promise.then(success, failure); 

     return deferred.promise; 

    } 

    service.save = function(success, failure){ 
     if(!failure){ failure = function(){};} 
     if(!success){ success = function(){};} 

     var deferred = $q.defer(); 

     API.Backups.O365.Exchange.update({id :$rootScope.ServiceId || $stateParams.serviceId}, Subscription, function(res){ 
      if(res.success){ 
       Subscription = res.result; // AFTER AN UPDATE IS MADE AND THE OBJECT IS SAVED, I TRY TO SET THE RESULT TO Subscription. 
       deferred.resolve(res); 
      }else{ 
       deferred.reject(res); 
      } 
     }, function(res){ 
      deferred.reject(res); 
     }); 

     deferred.promise.then(success, failure); 

     return deferred.promise; 
    } 


    service.get = function(){ 
     return Subscription; 
    } 

    return service; 


}); 

所以这个问题似乎试图使用Subscription作为一个集中的资源,用于存储模型来阻止,但该模型无法正确更新。

+0

没有得到什么问题是?客户端上的这个对象可能与服务器上的不一样?你不能避免它。并且'保存'通常包含没有完全更新的对象... –

+0

当然是的。我知道HTTP和API的工作方式。我强制客户端始终用服务器的更新进行更新,因为所有调用(GET和POST)都使用完整的'Subscription'对象进行响应 –

+0

问题肯定与分配不在内存中的相同位置上发生作用有关。 'Subscription = res.result'行似乎分配给闭包中的不同变量或者其他东西,因此永远不会正确更新 –

回答

0

如果您希望在整个服务期间更新Subscription模型,我建议您在控制器中调用MailboxSubscription.fetch()MailboxSubscription.save()时,您会在中使用MailboxSubscription.get()then()您的通话方式。

// get initial value of Subscription model 
$scope.Subscription = MailboxSubscription.get(); 


// let's fetch  
MailboxSubscription.fetch().then(
    // callback 
    function() { 
     // let's get the updated model 
     $scope.Subscription = MailboxSubscription.get(); 
    }, 
    // errback 
    function() { 
     // handle error 
    } 
); 

// let's save 
MailboxSubscription.save().then(
    // callback 
    function() { 
     // let's get the updated model 
     $scope.Subscription = MailboxSubscription.get(); 
    }, 
    // errback 
    function() { 
     // handle error 
    } 
); 

此外,我创建了working jsfiddle简化您的用例。它工作正常。也许有什么可以从闪烁(我使用$超时欺骗您的API调用)。