在呈现任何视图或控制器激活之前,在ui路由中进行条件解析

时间:2015-10-22 15:40:03

标签: angularjs api angular-ui-router ionic

经过两天的研究和失败理解承诺和$ q,我将描述我的问题 我创建了使用外部API的服务

.factory('Product', function($http, BASEURL) {
    return {
        get: function(id) {
            return $http.get(BASEURL + '/products/' + id);
        }
    };
})

其中一个州是产品状态,我可以用代码解析产品:

.state('app.product', {
    url: '/product/:id',
    resolve: {
        productData: function(Product, $stateParams) {
            return Product.get($stateParams.id)
            }
    },
    templateUrl: 'templates/product.html',
    controller: 'ProductCtrl'
})

但是,如果找不到id的产品,我需要将用户重定向到“产品不存在创建新”状态 和API返回状态404。

在获取所有需要的数据并且在控制器呈现状态之前,解析块中是否可以使用“if语句”?

这是我失败的方法

function productData($q, Product, $stateParams, $state) {
    var deferred = $q.defer();
    Product.get($stateParams.id)
    .then(function(result) {
        if (result.status != 404) { //the service responds with full response not the "API response" 
            deferred.resolve(result);
            return deferred.promise;
        } else {
            $state.go('app.notFound');

        }
    });
}

我还需要与其他资源进行相同的错误处理

我也尝试过没有服务直接访问api并且它有点工作

.state('app.product', {
    url: '/product/:id',
    resolve: {
        productData: checkProductExists
    },
    templateUrl: 'templates/product.html',
    controller: 'ProductCtrl'
})

function checkProductExists($q, $stateParams, $state, $http) {

    var deferred = $q.defer();
    $http.get('https://example.com/api/products/id' + $stateParams.id)
        .success(function(response) {
            if (response.status_code != 404) { //the $http responds with "API response" where i have custom error status codes
                deferred.resolve(response);
            } else {
                deferred.reject();
                $state.go('app.notFound');
            }
        })
        .error(function() {
            deferred.reject();
            $state.go('app.notFound');
        });
    return deferred.promise;

};

2 个答案:

答案 0 :(得分:0)

$http.get工厂中的

Product会返回一个承诺,允许您resolve访问GET请求的结果。

您目前拥有它的方式,productData持有承诺而不是您的实际数据。

Refer to the Promise API

  

然后(successCallback,errorCallback,notifyCallback) - 无论何时或将要解决或拒绝承诺,然后异步调用其中一个成功或错误回调很快就会有结果。使用单个参数调用回调:结果或拒绝原因。此外,在解决或拒绝承诺之前,可以将通知回调调用零次或多次以提供进度指示。

尝试将resolve修改为

.state('app.product', {
    url: '/product/:id',
    resolve: {
        productData: function(Product, $stateParams) {
            Product.get($stateParams.id).then(function (response) { 
                // successCallback for .then()
                return response.data;
            }, function (error) { 
                // errorCallback for .then() 
                return {};
            });
        }
    },
    templateUrl: 'templates/product.html',
    controller: 'ProductCtrl'
})

现在,您可以在productData中注入ProductCtrl并随意处理数据,如果$state.go('app.notFound');为空,可能会productData

答案 1 :(得分:0)

我只是通过添加return关键字来解决它,以获得已解决的承诺。更新的代码:

.state("cards.newcard", {
            url: "/newcard",
            cache: false,
            templateUrl: "Cards/NewCard",
            controller: "newCardController",
            resolve:
                    {
                        customerProfile: ['customerService', '$rootScope', '$translate', function (customerService, $rootScope, $translate) {
                            return customerService.getCustomerProfile($rootScope.authentication.userName, "", $translate.use()).then(
                            function (response) {
                                return response;
                            },
                            function (error) {
                                return {};
                            });
                            //return customerService.getCustomerProfile($rootScope.authentication.userName, "", $translate.use());

                        }]
                    }
        })