2014-01-06 1 views
1

Я пытаюсь создать службу, которая будет содержать содержимое корзины на моем сайте с помощью AngularJS. Затем я использую это, чтобы убедиться, что ссылка на корзину во всех контроллерах и т. Д. Должна быть на том же объекте и синхронизирована.Инициализировать служебные данные с помощью запроса 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; 
} 

Допустим, что переменная отложила выше является объектом более ОС менее, как это:

{ 
    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() обещание (отложенное.), и это позволяет вызываемому устанавливать обратные вызовы, которые будут выполняться всякий раз, когда обещание изменяет свое состояние (разрешать, отклонять или уведомлять).

Таким образом, внутри нашего контроллера я устанавливаю только обратный вызов разрешения, если обещания отклоняются, это произойдет молча, потому что не будет выполнена ошибка, которая будет выполнена.

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

Конечно, есть намного больше за ним, но я думаю, что это упрощенно обещание поможет вам получить основную идею. Имейте в виду, что cartFactory.getItems() всегда должен возвращать обещание, даже если элементы уже загружены, иначе cartFactory.getItems(). Then() будет ломаться, если, например, вы возвращаете массив.

Here a JSBin с вашим сервисом cartFactory, я использую $ timeout для имитации асинхронного вызова.

Надеюсь, это поможет.

+1

Это работает, большое спасибо Бертран, очень ценю ваш образец кода. – mr1031011

Смежные вопросы