简体   繁体   English

角嵌套承诺

[英]Angular Nested Promise

I'm really struggling to write a complex function in Angular that depends on promises. 我真的很难在Angular中编写依赖于promise的复杂函数。 This is my first time writing a promise and I'm still not sure I fully understand how to do what I want to do with my code. 这是我第一次写一个诺言,但我仍然不确定我是否完全理解如何使用我的代码来做。

I have a variable var query = searchQuery.getQuery() in a controller ProfileNavCtrl . 我在控制器ProfileNavCtrl有一个变量var query = searchQuery.getQuery() Then in my searchQuery service, getQuery fetches the value of localStorage.getItem('searchQuery') and checks if it's an empty string or null. 然后在我的searchQuery服务中, getQuery获取localStorage.getItem('searchQuery')的值,并检查它是否为空字符串或null。 If it's not empty or null, it simply returns the value to the controller. 如果它不为空或为null,则仅将值返回给控制器。 The value should be an array of slugs like ['foo','foo-bar','foo-bar-baz'] . 该值应为['foo','foo-bar','foo-bar-baz']类的子数组。

If it is null or empty, it executes an $http.get call to fetch a JSON object and parse it. 如果为null或为空,它将执行$http.get调用以获取JSON对象并进行解析。 This is where things break down for me. 这是我无法解决的地方。 I need getQuery() to return the value from $http.get (if the initial value of query is null) so that the controller variable query is assigned that value. 我需要getQuery()$http.get返回值(如果query的初始值为null),以便为控制器变量query分配该值。 As it is now, query (in the controller) is always set to null or undefined. 现在, query (在控制器中)始终设置为null或未定义。

The $http.get call also calls setQuery() so that the query is persisted and future calls are avoided. $http.get调用还调用setQuery()以便持久setQuery()查询并避免以后的调用。

Here is my controller: 这是我的控制器:

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

And here is my service: 这是我的服务:

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: 2nd Attempt Here is my controller code: var getQuery = searchQuery.getQuery(); 更新:第二次尝试这是我的控制器代码: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);
        }
    };
});

Here is my updated service: this.getQuery = function(){ return new Promise(function(){ var query = localStorage.getItem('searchQuery'); 这是我更新的服务:this.getQuery = function(){返回新的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;
        };
    });
};

In Angular promises are provided through the $q service. 在Angular中,承诺是通过$q服务提供的。 See the documentation for more detail. 有关更多详细信息,请参见文档

The basic outline to implement $q promise in your service is outlined below, I'll leave the detail on how to save to local storage etc to you: 下面概述了在您的服务中实现$ q promise的基本概述,下面将向您详细介绍如何保存到本地存储等:

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;
};

You can then use this in your controller like: 然后,您可以在控制器中使用它,例如:

var query = null;
searchQuery.getQuery().then(function(result) {
    query = result;
}, function(err) {
    // Error occured
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM