Angularjs 在状态更改之前解析承诺

Angularjs 在状态更改之前解析承诺,angularjs,angular-ui-router,angular-ui-router-extras,Angularjs,Angular Ui Router,Angular Ui Router Extras,我正在使用ui路由器和ui路由器附加程序 $scope.$on('$transitionStart', function (e, $transition$) { var params = {id:1}; factory.webService(params) .success(function (data) { if (data.d == "Expired") {//Inspects the application session

我正在使用ui路由器和ui路由器附加程序

$scope.$on('$transitionStart', function (e, $transition$) {
    var params = {id:1};
    factory.webService(params)
        .success(function (data) {
            if (data.d == "Expired") {//Inspects the application session
                //Stops the state request and sents you to the login screen
                e.preventDefault();
                location.href = "login.html";
            }
            else if (data.d == "NotAllowed") {
                //Stops the state request and keeps you on the state you already are
                e.preventDefault();
            } else {
                //Proceed to load the requested state
            }
        })
        .error(function (data, status) {
            alert(data.Message);
        });
});
我需要在加载$stateChangeStart之前解决成功部分,但我不知道如何执行

有没有办法做到这一点

编辑

我的代码是这样的

.state('myState', {
        url: "/myState",
        templateUrl: 'views/template.html',
        controller: 'ctrlTemplate',
        viewId: 99,
        resolve: {
            fn: function ($stateParams, myFactory) {
                myFactory.checkSession({viewId:99})
                .then(function onSuccess(response) {
                    var data = response.data;
                    if (data.d == "Expired") {
                        throw "Expired";
                    }
                    else if (data.d == "NotAllowed") {
                        throw "NotAllowed";
                    } else {
                        //RETURN to chain data
                        return data;
                        //Proceed to load the requested state
                    }
                })
                .catch(function (response) {
                    //e.preventDefault();
                });
            }
        }
    })
$http
.then
函数在发生
$stateChangeStart
$transitionStart
且新状态已加载后仍在解析。我可以在浏览器控制台调试器中看到它的发生


Plz帮助。

是的,有更优雅的方法:

例如:

$stateProvider.state('users.profile', {
  url: '/:id',
  templateUrl: 'views/users.profile.html',
  controller: 'UsersController',
  resolve: {
    user: function($stateParams, UserService) {
      return UserService.find($stateParams.id);
    },
    tasks: function(TaskService, user) {
      return user.canHaveTasks() ?
        TaskService.find(user.id) : [];
    }
  }
});
有关更多详细信息,请阅读以下文章

我需要等待$http响应并在
.success
函数中捕获它

.success
方法不能拒绝承诺,但
方法可以将成功转换为拒绝:

var promise = factory.webService(params)
    //.success(function (data) {
    .then( function onSuccess(response) {
        var data = response.data;
        if (data.d == "Expired") {
            //THROW to create a rejected promise
            throw "Expired";
            /*
            //Inspects the application session
            //Stops the state request and sents you to the login screen
            e.preventDefault();
            location.href = "login.html";
            */
        }
        else if (data.d == "NotAllowed") {
            //THROW to create a rejected promise
            throw "NotAllowed";
            /*
            //Stops the state request and keeps you on the state you already are
            e.preventDefault();
            */
        } else {
            //RETURN to chain data
            return data;
            //Proceed to load the requested state
        }
    })
    //.error(function onError(data, status) {
    .catch( function(response) {
        var data = response.data;
        var status = response.status;
        alert(data.Message);
        //THROW to chain rejection
        throw data.Message;
    });
});
通过使用
return
throw
语句,从httpPromise的
.then
.catch
方法解析的响应创建新的派生承诺

当ui路由器状态的解析器函数获得拒绝的承诺时,状态更改将中止


更新 所以我有这样的代码

    //ERRONEOUS
    resolve: {
        fn: function ($stateParams, myFactory) {
            myFactory.checkSession({viewId:99})
            .then(function onSuccess(response) {
                var data = response.data;
                if (data.d == "Expired") {
                    throw "Expired";
                }
我不明白为什么抛出不会触发$stateChangeError

解析器功能需要将承诺返回给路由器:

    resolve: {
        fn: function ($stateParams, myFactory) {
          //vvvvvv RETURN the promise
            return myFactory.checkSession({viewId:99})
            .then(function onSuccess(response) {
                var data = response.data;
                if (data.d == "Expired") {
                    throw "Expired";
                }
当函数省略
return
语句时,该函数将返回
undefined
的值。在这种情况下,路由器认为其值为
undefined
时成功

      //CORRECT   
            })
            .catch(function (response) {
                //THROW to chain rejection
                throw response;
                //e.preventDefault();
            });
而且
.catch
方法是错误的

.catch
方法的拒绝处理程序忽略
return
(或
throw
)语句时,函数返回
undefined
的值。这将把拒绝转换为一个成功的承诺,该承诺的值为
undefined

      //CORRECT   
            })
            .catch(function (response) {
                //THROW to chain rejection
                throw response;
                //e.preventDefault();
            });
函数式编程的经验法则是--总是返回一些东西


在承诺成功和拒绝的情况下:始终
返回
抛出
某物。

我忘了提到,工厂返回$http,因此我需要等待$http响应,并在成功函数中捕获它,可能我不理解page@ChildGG,只需将工厂注入解析对象中的一些
数据
,如示例中的
UserService
。之后,只需返回您在问题中分配给PROMITE变量的相同实现。@ChildGG很乐意提供帮助。如果有帮助,请投票并接受我的答案。干杯你好,georgeawg,多亏了Tome和你,我在状态更改之前获得了响应,但现在我不明白为什么抛出没有触发$stateChangeErrorResolver函数没有返回派生的承诺。见补充答案。