Угловое Вложенное Обещание

0

Im действительно изо всех сил пытается написать сложную функцию в Angular, которая зависит от обещаний. Это мой первый раз, когда я пишу обещание, и я все еще не уверен, что полностью понимаю, как делать то, что я хочу делать с моим кодом.

У меня есть переменная var query = searchQuery.getQuery() в контроллере ProfileNavCtrl. Тогда в моей searchQuery службе, getQuery получает значение localStorage.getItem('searchQuery') и проверяет, если его пустая строка или нуль. Если его значение не пустое или пустое, оно просто возвращает значение контроллеру. Значение должно быть массивом таких пулов, как ['foo','foo-bar','foo-bar-baz'].

Если он пустой или пустой, он выполняет вызов $http.get для извлечения объекта JSON и его анализа. Здесь меня ломают вещи. Мне нужно getQuery() чтобы вернуть значение из $http.get (если начальное значение query равно NULL), так что для query переменной контроллера присваивается это значение. Как и сейчас, query (в контроллере) всегда имеет значение null или undefined.

$http.get также вызывает setQuery() чтобы запрос сохранялся и избегались будущих вызовов.

Вот мой контроллер:

app.controller('ProfileNavCtrl', ['$scope', '$http', '$location', '$q', 'searchQuery',
function($scope, $http, $location, $q, searchQuery){
    var query = searchQuery.getQuery;
// do something with query

И вот мое служение:

app.service('searchQuery', ['$http', '$timeout', '$q', function($http, $timeout, $q){
    var query = [];

    this.getQuery = new Promise(function(){
        var query = localStorage.getItem('searchQuery');

        if(query == "" || query == [""] || query == null){
            var slugArray = [];
            var query = $http.get('/companies.json')
            .then(function(resp) {
                if(resp && resp.data) {
                    for(var i in resp.data) {
                        var result = resp.data[i];
                        if(resp.data[i].name){
                            slugArray.push(resp.data[i].name.toLowerCase().split(' ').join('-'));
                        }
                    }
                    setQuery(slugArray);
                } else {
                    resetQuery();
                }
            }, function(err) {
                resetQuery();
            }).then(function(resp){
                return resp;
            })
            return query;
        } else {
            return query;
        };
    }).then(function(success){
        return success;
    });

UPDATE: 2-ая попытка. Вот мой код контроллера: var getQuery = searchQuery.getQuery();

getQuery.then(function(query){
    query = searchQuery.getQuery();
    // Check if user is on main site or portal
    if(location.pathname.split('/')[3] == null){
        var currentProfile = location.pathname.split('/')[1];
    } else {
        var currentProfile = location.pathname.split('/')[3];
    };

    // Get the next/prev query element (if any)
    console.log('6: ');
    console.log(query);
    var prev = query.slice(query.indexOf(currentProfile)-1)[0];
    var next = query.slice(query.indexOf(currentProfile)+1)[0];

    // Check if next/prev is undefined and if so, set to first/last element in query array
    if(prev){
        var prevProfile = prev;
    } else {
        var prevProfile = query.pop();
    };

    if(next){
        var nextProfile = next;
    } else {
        var nextProfile = query[0];
    };

    $scope.goToPrev = function() {
        // Check if user is on main site or portal
        if(location.pathname.split('/')[3] == null){
            var profileUrl = location.origin + '/' + prevProfile;
            // window.location = profileUrl;
            console.log(profileUrl);
        } else {
            var profileUrl = location.origin + '/' + location.pathname.split('/').slice(1,3).join('/') + '/' + prevProfile;
            // window.location = profileUrl;
            console.log(profileUrl);
        }
    };

    $scope.goToNext = function() {
        // Check if user is on main site or portal
        if(location.pathname.split('/')[3] == null){
            var profileUrl = location.origin + '/' + nextProfile;
            // window.location = profileUrl;
            console.log(profileUrl);
        } else {
            var profileUrl = location.origin + '/' + location.pathname.split('/').slice(1,3).join('/') + '/' + nextProfile;
            // window.location = profileUrl;
            console.log(profileUrl);
        }
    };
});

Вот моя обновленная услуга: this.getQuery = function() {return new Promise (function() {var query = localStorage.getItem('searchQuery');

        if(query == "" || query == [""] || query == null){
            var slugArray = [];
            return $http.get('/companies.json')
            .then(function(resp) {
                if(resp && resp.data) {
                    for(var i in resp.data) {
                        var result = resp.data[i];
                        if(resp.data[i].name){
                            slugArray.push(resp.data[i].name.toLowerCase().split(' ').join('-'));
                        }
                    }
                    setQuery(slugArray);
                } else {
                    resetQuery();
                }
                return slugArray;
            }, function(err) {
                resetQuery();
            });
        } else {
            return query;
        };
    });
};
Теги:
promise

1 ответ

1
Лучший ответ

В Угловые обещания предоставляются через службу $q. Более подробную информацию см. В документации.

Ниже приведен общий план реализации обещания $ q в вашем сервисе, я оставлю вам подробную информацию о том, как сохранить на локальном хранилище и т.д.:

this.getQuery = function(){
    var deferred = $q.defer();
    var query = localStorage.getItem('searchQuery');

    if(query == "" || query == [""] || query == null){
        $http.get('yoururl').then(function(resp) {
            // assuming resp is an array, else do your parsing to get array
            query = resp;
            deferred.resolve(query);
        }, function(err) {
            query = null;
            deferred.reject(err);
        });
    } else {
        deferred.resolve(query);
    };
    return deferred.promise;
};

Затем вы можете использовать это в своем контроллере, например:

var query = null;
searchQuery.getQuery().then(function(result) {
    query = result;
}, function(err) {
    // Error occured
});
  • 0
    Я попробовал подобную настройку, прежде чем это не сработало для меня. С тех пор я отказывался от использования deferred поскольку прочитал несколько постов в блоге, таких как этот, которые говорят, что это плохая практика. Я отправил свою вторую попытку в моем вопросе. Теперь у меня есть обещание, доставленное на контроллер, я просто не знаю, что с ним делать.
  • 0
    $q - это реализация обещаний Angular, тесно интегрированная во все встроенные сервисы Angular. q$ может использоваться либо с отложенным способом, либо с чем-то похожим на обещания ES6 в некоторой степени. Но deferred моды - безусловно, самый распространенный способ в Angular и сторонних модулях Angular. В любом случае, вам остается использовать $q а не обещания ES6 напрямую, как вы сейчас пытаетесь это сделать. $q также интегрируется с механизмом наблюдения прицельной модели в угловых.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню