UI路由器中的嵌套解析无法解析

时间:2016-03-21 04:04:37

标签: angularjs angular-ui-router

我正在尝试将UI-Router解析的结果传递给UI-Router中的另一个解析方法,但我发现每次执行此操作时,以下(嵌套)方法都无法解析。

下面的代码应解析有关用户的信息(此处称为SellerData),将相关参数传递给访问检查(称为SubscriptionId),并使用这两个值获取一些信息({{1如果我将结果硬编码到方法中(即用sanitizedProduct中的值替换SellerData.product.id),所有这些代码都可以独立工作,但是一旦我传递一个已解析的对象,代码就会失败并产生结果页面从不加载。

我完全有可能把这个东西的嵌套性质弄错了但是我担心我没有看到关于这个问题的大量信息所以这是我花了很多时间后最好的猜测孤立的东西。

更新3.19

基于来自Estus的this answer,很明显我犯了一个错误(我愚蠢地假设解析调用是同步的)但代码仍然没有正确解析。使用此版本getSubscriptionIdSellerData正确解析并按正确顺序解析SubscriptionId方法未被调用

getSanitizedProduct

获取有关在以下方法和页面绑定中使用的卖家的信息

.state('subscriberArea', {
    url: '/:creatorUsername/subscriber',
    templateUrl: 'modules/subscriber/client/views/subscriberArea.client.view.html',
    controller: 'SubscriberAreaController',
    controllerAs: 'vm',                 
    resolve: {
        SellerData: getSellerData,
        SubscriptionId: getSubscriptionId,
        sanitizedProduct: getSanitizedProduct,
    },
    data: {
        pageTitle: 'Subscriber'
    }
})

查找用户对象上的值(称为“身份验证”)是否与从getSellerData解析的产品ID匹配,并将该值设置为“SubscriptionId”解析

getSellerData.$inject = ['$stateParams', 'UserData', '$q', '_'];
function getSellerData($stateParams, UserData, $q, _){
    // Creates query to be passed to 'UserData' service that queries mongo
    var deferred = $q.defer();
    var query = {'username': $stateParams.creatorUsername};
    return UserData.findOne(query).then(function(seller){
        // Adds essential information from query to new object that will be returned to the resovle
        var sellerData = {};
        sellerData._id = seller._id;
        sellerData.product.id = seller.product.id;  
        deferred.resolve(sellerData);
        return deferred.promise;
    });
}       

使用已解析的SellerData和SubscriptionId信息查询数据库

getSubscriptionId.$inject = ['Authentication', '_', '$q', 'SellerData'];
function getSubscriptionId(Authentication, _, $q, SellerData){
    var promises = [SellerData];
    $q.all(promises).then(function(resolved){
        var sellerData = resolved[0];
        var subscriptionId = _.intersection(Authentication.user.purchases, sellerData.product.id);
        deferred.resolve(subscriptionId);
        return deferred.promise;
    })
}

ORIGINAL

基本UI-Router设置:

getSanitizedProduct.$inject = ['ProductData', 'SellerData', 'SubscriptionId', '$q'];
function getSanitizedProduct(ProductData, SellerData, SubscriptionId, $q){
    var promises = [SellerData, SubscriptionId];
    $q.all(promises).then(function(resolved){
        var sellerData = resolved[0]
        var subscriptionId = resolved[1]
        var productId = sellerData.product.id;
        var versionId = {'version': subscriptionId};
        return ProductData.getWhitelistedData(productId, versionId).then(function(product){
            // plain() is a Restangular method that strips unnecessary properties
            return product.plain();
        });
    }
}

获取有关在以下方法和页面绑定中使用的卖家的信息

.state('subscriberArea', {
    url: '/:creatorUsername/subscriber',
    templateUrl: 'modules/subscriber/client/views/subscriberArea.client.view.html',
    controller: 'SubscriberAreaController',
    controllerAs: 'vm',                 
    resolve: {
        SellerData: getSellerData,
        SubscriptionId: getSubscriptionId,
        sanitizedProduct: getSanitizedProduct,
    },
    data: {
        pageTitle: 'Subscriber'
    }
})

查找用户对象上的值(称为“身份验证”)是否与从getSellerData解析的产品ID匹配,并将该值设置为“SubscriptionId”解析

getSellerData.$inject = ['$stateParams', 'UserData', '_'];
function getSellerData($stateParams, UserData, _){
    // Creates query to be passed to 'UserData' service that queries mongo
    var query = {'username': $stateParams.creatorUsername};
    return UserData.findOne(query).then(function(seller){
        // Adds essential information from query to new object that will be returned to the resovle
        var sellerData = {};
        sellerData._id = seller._id;
        sellerData.product.id = seller.product.id;
        return sellerData;
    });
}       

使用已解析的SellerData和SubscriptionId信息查询数据库     getProduct。$ inject = ['ProductData','SellerData','SubscriptionId'];

getSubscriptionId.$inject = ['Authentication', '_', 'SellerData'];
function getSubscriptionId(Authentication, _, SellerData){
    return _.intersection(Authentication.user.purchases, SellerData.product.id);
}

1 个答案:

答案 0 :(得分:0)

PreparedStatementSellerData是本地依赖项,它们特定于路由控制器。控制器的本地依赖性不适用于应用程序范围内的注入,并且解析器在这方面没有区别。路径控制器是唯一可以注入路由解析器的地方。

此外,SubscriptionId是一个对象,而不是一个数组。这意味着无法保证解析器的执行顺序。如果承诺必须以特定顺序执行,则始终使用resolve,如果必须执行已确定,则始终使用它们链 em>特别有序。

所有解析器($q.allSellerDataSubscriptionId)应该成为单独的服务(很可能是sanitizedProduct而不是service),最后一个在链中(factory)应该用作路线解析器。