2014-01-06 23 views
1

我正在嘗試使用AngularJS創建一個服務,該服務將保存我的網站的購物車內容。然後,我將使用它來確保在所有控制器等中對購物車的引用應該對同一個對象進行同步。使用promise以ajax請求初始化服務數據?

問題是購物車內容必須通過ajax調用進行初始化。我的下面的代碼不起作用,但它顯示了我想要完成的。我想以某種方式獲取項目列表並返回getItems(),但如果項目列表還沒有被提取,那麼我將需要首先獲取它並承諾返回。我正試圖圍繞「承諾」概念包圍我的頭,但到目前爲止我還沒有完全掌握它。

factory('cartFactory', function ($rootScope, Restangular) { 
    var cart = $rootScope.cart = {}; 

    return { 
     getItems: function() { 
      if (undefined == cart.items) { 
       return Restangular.oneUrl('my.api.cart.show', Routing.generate('en__RG__my.api.cart.show')).get().then(function($cart){ 
        cart = $rootScope.cart = $cart; 

        angular.forEach(cart.items, function(value, key){ 
         cart.items[key]['path'] = Routing.generate('en__RG__my.frontend.product.info', {'slug': value.variant.product.slug}); 
        }); 

        return cart.items; 
       }); 
      } else { 
       return cart.items 
      } 
     }, 
     setItems: function ($items) { 
      cart.items = $items; 
     }, 
     removeItem: function ($item) { 
      cart.splice(cart.indexOf($item), 1); 
     }, 
     addItem: function ($item) { 
      cart.items.push($item) 
     } 
    } 
}) 

回答

1

我會盡量以非常簡單的方式解釋這一點。

一個承諾僅僅是被「傳來傳」的對象,我們使用這個對象來連接,每當我們解決將要執行的功能,拒絕或通知的承諾。

由於JavaScript對象按引用傳遞我們能夠指向同一個對象在幾個地方,在我們的情況下,服務和控制器內。

在我們的服務,我們執行:

getItems: function() { 
    var deferred = $q.defer(); 

    // do async stuff 

    return deferred.promise; 
} 

比方說,以上推遲變量是一個對象多個OS少這樣的:

{ 
    reject: function (reason) { 
     this.errorCallback(reason); 
    }, 
    resolve: function (val) { 
     this.successCallback(val); 
    }, 
    notify: function (value) { 
     this.notifyCallback(value); 
    }, 
    promise: { 
     then: function (successCallback, errorCallback, notifyCallback) { 
      this. successCallback = successCallback; 
      this.errorCallback = errorCallback; 
      this.notifyCallback = notifyCallback; 
     } 
    } 
} 

所以,當我們調用getItems()一個承諾( deferred.promise)被返回,並且這允許被調用者設置當承諾改變其狀態(解析,拒絕或通知)時執行的回調。

所以我們的控制器裏面,我只把決心回調,如果承諾被拒絕,因爲沒有被執行errorCallback它會悄悄發生。

cartFactory.getItems().then(function (items) { 
    $scope.items = items; 
}); 

當然有更多的背後,但我認爲這個簡單的承諾將幫助你獲得基本的想法。請注意,即使已加載項目,cartFactory.getItems()也必須始終返回一個承諾,否則如果返回數組,則cartFactory.getItems()。then()將中斷。

Here a JSBin你cartFactory服務,我使用$超時來模擬一個異步調用。

希望這會有所幫助。

+1

它的工作原理非常感謝伯特蘭非常感謝您的示例代碼。 – mr1031011