Angular Firebase, извлекающий один элемент, имеет условия гонки

Я использую angular и firebase вместе, и у меня есть массив продуктов, который я храню в своей корневой области, хотя для загрузки элементов требуется время.

Моя проблема заключается в том, что когда я перехожу на эту страницу, например, напрямую: http://localhost/product/greyish-sports-shoes

Если я перехожу на домашнюю страницу, продукты загружаются через 2 секунды ... и только тогда, когда я нажимаю на ссылку продукта, я попадаю на нее, и это будет работать, потому что продукты уже были загружены.

Он обращается к ShoeService, содержащему массив товаров, но товары все еще не загружены, поэтому он не может найти товар по его слагу.

Это код, который я использую в своем методе запуска.

   var ref = firebase.database().ref().child('products');

    $rootScope.shopProds = $firebaseArray(ref);

Моя обувная фабрика:

 function shoeFactory($rootScope) {
    this.service = {};

    this.service.store = new Store($rootScope.shopProds);
    this.service.cart = new Cart();

    return this.service;
}

person Paul Diamant    schedule 19.03.2017    source источник


Ответы (1)


Важно понимать, что служба $firebaseArray возвращает массив, который изначально пуст. Массив заполняется асинхронно после получения данных с сервера.

Используйте обещание, возвращаемое методом $loaded, прикрепленным к массиву:

function shoeFactory($rootScope) {
    this.service = {};

    this.service.storePromise = $rootScope.shopProds.$loaded()
      .then ( (shopProds) => {
         return new Store(shopProds);
    });                   

    this.service.cartPromise = this.service.storePromise
      .then ( () => {
        return new Cart();
    }).catch( (error) => {
        console.log("ERROR in shoeFactory");
        throw error;
    }); 

    return this.service;
}

Чтобы избежать условий гонки, код должен использовать обещания для цепочек операций.

person georgeawg    schedule 19.03.2017
comment
Спасибо. Есть ли способ в angular 1 узнать, не загружено ли состояние пользовательского интерфейса? Я знаю, что это можно сделать в методе запуска с помощью stateChangeFinished. - person Paul Diamant; 19.03.2017
comment
Для этого нужен новый вопрос, объясняющий контекст, вариант использования и пример, показывающий, что вы пробовали до сих пор. - person georgeawg; 19.03.2017