2015-01-16 104 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調用)。