【问题标题】:Angular: How to access resolved values in UI-Router in controllerAngular:如何在控制器的 UI-Router 中访问已解析的值
【发布时间】:2016-07-02 05:45:18
【问题描述】:

我无法访问在控制器中以我的 ui-router 状态解析的密钥

当前处于子状态,在显示模板之前会发出 http 请求以检查用户是否已通过身份验证。如果没有,在 onEnter 部分它会重定向到另一个状态。

这行得通,但我也想在显示的视图中访问已解析的数据 我不知道如何访问控制器中的已解析键(将其分配给范围属性)或直接在视图中(这应该可以通过角度 1.5.0 中引入的 $scope.$resolve 实现)。 我尝试使用密钥、@resolve 属性等注入控制器。到目前为止,我在谷歌搜索这个问题时得到的所有工作示例都对我不起作用。

这是状态:

.state('login.resetPassword',{
    url: '/resetPassword/{validateToken}'
    ,resolve: {
        validateResponse: function($stateParams,AuthService,SessionService){
                            return AuthService.validatePasswordResetToken($stateParams.validateToken)
                            .then(function(validateResponse){
                                SessionService.set('validateToken',$stateParams.validateToken);
                                return validateResponse.data; //{validate_ok:true/false,message:I18nKey}
                            })
        }
    }
    ,onEnter: function($stateParams,$state,validateResponse){
        if(validateResponse.validate_ok){
            // do nothing, go to resetPassword
        }
        else{
            $state.go('message',{message:validateResponse.message});
        }
    }
    ,views: {
        'forgotPassword': {
            templateUrl: '/app/components/login/views/resetPassword.html'
        }
    }
})

在开发人员工具中,我看到 validateResponse 解析正常,在 onEnter 函数中,我看到已解析的键 'validateResponse' 带有参数中的值。

在控制器中我尝试访问已解析的属性:

['validateResponse',function(validateResponse){
console.log('validateResponse: ',validateResponse)
...
}]

(为简洁起见,此处仅显示相关部分)

...但是调试器甚至从来没有到达 console.log 的那一行。 在视图中,我在 $scope 中没有 validateResponse 属性...没有 $console.log() 或 Batarang 范围视图

父状态包含对控制器的引用,但即使我将控制器移动到子状态也没有区别:

这里有什么问题??????

【问题讨论】:

    标签: angularjs angular-ui-router resolve


    【解决方案1】:

    尝试在 state 中引用您的控制器:

    .state('login.resetPassword',{
        url: '/resetPassword/{validateToken}'
        ,resolve: {
            validateResponse: function($stateParams,AuthService,SessionService){
                                return AuthService.validatePasswordResetToken($stateParams.validateToken)
                                .then(function(validateResponse){
                                    SessionService.set('validateToken',$stateParams.validateToken);
                                    return validateResponse.data; //{validate_ok:true/false,message:I18nKey}
                                })
            }
        }
        ,onEnter: function($stateParams,$state,validateResponse){
            if(validateResponse.validate_ok){
                // do nothing, go to resetPassword
            }
            else{
                $state.go('message',{message:validateResponse.message});
            }
        }
        ,controller: ['validateResponse',function(validateResponse){
            console.log('validateResponse: ',validateResponse);            
        }]
        ,views: {
            'forgotPassword': {
                templateUrl: '/app/components/login/views/resetPassword.html'
            }
        }
    })
    

    【讨论】:

    • 如果我像你建议的那样添加控制器内联(我为什么要这样做?我的控制器 >100 行......太大而不能包含内联)并添加断点,然后首先解决解析,然后onEnter 和带有 console.log('validateResponse: ',validateResponse); 的行永远不会被击中......
    • 我不太明白你的评论。 console.log() 执行了吗?确实它太大了,不能内联,但你可以把它放在一个变量中,比如var resetPasswordController = ['validateResponse',function(validateResponse){ ... }],然后在你的状态中引用它为, controller: resetPasswordController
    • 啊,我明白你的意思了。 RE 你的问题'console.log() 执行了吗?答案是不。我怀疑这里有一些不同的地方是错误的,因为看起来控制器在父状态“登录”中被“命中”后根本没有更新。这个状态是'login.resetPassword'。也许必须将“,控制器:'AuthController'”移回......
    【解决方案2】:

    好的,似乎终于解决了...我必须将控制器包含在子状态的解析块中,因此它会得到更新。还要在控制器中注入已解析的密钥:

    .state('login.resetPassword',{
        url: '/resetPassword/{validateToken}'
        ,resolve: {
            validateResponse: function($stateParams,AuthService,SessionService){
                                return AuthService.validatePasswordResetToken($stateParams.validateToken)
                                .then(function(validateResponse){
                                    SessionService.set('validateToken',$stateParams.validateToken);
                                    return validateResponse.data;                             })
            }
        }
        ,onEnter: function($stateParams,$state,validateResponse){
            if(validateResponse.validate_ok){
                // do nothing, go to resetPassword
            }
            else{
                $state.go('message',{message:validateResponse.message});
            }
        }
        ,views: {
            'forgotPassword': {
                templateUrl: '/app/components/login/views/resetPassword.html'
            }
        }
    })
    

    应该变成

    .state('login.resetPassword',{
        url: '/resetPassword/{validateToken}'
        ,resolve: {
            validateResponse: function($stateParams,AuthService,SessionService){
                                return AuthService.validatePasswordResetToken($stateParams.validateToken)
                                .then(function(validateResponse){
                                    SessionService.set('validateToken',$stateParams.validateToken);
                                    return validateResponse.data;                             })
            }
        }
        ,onEnter: function($stateParams,$state,validateResponse){
            if(validateResponse.validate_ok){
                // do nothing, go to resetPassword
            }
            else{
                $state.go('message',{message:validateResponse.message});
            }
        }
        ,views: {
            'forgotPassword': {
                templateUrl: '/app/components/login/views/resetPassword'
                ,controller:'AuthController'
    
            }
        }
    })
    

    和控制器:

    angular.module('myApp')
    .controller('AuthController',
        ['$scope','validateResponse',
    function($scope,validateResponse){
    
            console.log('validateResponse = ',validateResponse);
    ...
    

    【讨论】:

      【解决方案3】:

      所以现在我得到另一个错误... 我在控制器中注入了 validateResponse 对象,它只在子状态('login.resetPassword')中被实例化。没关系,但是父状态不知道该对象,因为它在该状态(“登录”)下不进行解析。因此出现此错误:

      angular.js:13236 Error: [$injector:unpr] Unknown provider: validateResponseProvider <- validateResponse <- AuthController
      

      我猜我这里需要单独的控制器。

      【讨论】:

        猜你喜欢
        • 2015-04-25
        • 1970-01-01
        • 2015-02-24
        • 2016-02-18
        • 1970-01-01
        • 1970-01-01
        • 2017-04-16
        • 2023-03-11
        • 1970-01-01
        相关资源
        最近更新 更多