在状态改变之前解决承诺 UI-Router
Resolve a promise before state changes UI-Router
我正在使用 ui-router 和 ui-router extras
$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
发生后仍在解析,新状态已经加载。我可以在浏览器控制台调试器中看到它发生
请帮忙。
是的,有更优雅的方法:resolve by ui-router
示例:
$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) : [];
}
}
});
有关详细信息,请阅读 Advanced routing and resolves 上的以下文章。
i need to wait for the $http response and catch it on the .success
function
.success
方法 无法拒绝承诺,但 .then
方法能够 转换 成功拒绝:
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-router 状态的解析器函数收到拒绝的承诺时,状态更改将中止。
更新
So I have my code like this ...
//ERRONEOUS
resolve: {
fn: function ($stateParams, myFactory) {
myFactory.checkSession({viewId:99})
.then(function onSuccess(response) {
var data = response.data;
if (data.d == "Expired") {
throw "Expired";
}
I can't understand why the throw doesn't trigger the $stateChangeError.
解析器功能需要return对路由器的承诺:
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
语句时,函数 return 的值为 undefined
。在这种情况下,路由器认为它是成功的,值为 undefined
.
还有.catch
方法是错误的
//ERRONEOUS
})
.catch(function (response) {
//e.preventDefault();
});
当 .catch
方法的拒绝处理程序省略 return
(或 throw
)语句时,函数 return 的值为 undefined
。这将 将拒绝转换为 成功的承诺,该承诺的解析值为 undefined
。
//CORRECT
})
.catch(function (response) {
//THROW to chain rejection
throw response;
//e.preventDefault();
});
函数式编程的经验法则是——总是return某事。
在承诺成功和拒绝的情况下:总是 return
或 throw
某事。
我正在使用 ui-router 和 ui-router extras
$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
发生后仍在解析,新状态已经加载。我可以在浏览器控制台调试器中看到它发生
请帮忙。
是的,有更优雅的方法:resolve by ui-router
示例:
$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) : [];
}
}
});
有关详细信息,请阅读 Advanced routing and resolves 上的以下文章。
i need to wait for the $http response and catch it on the
.success
function
.success
方法 .then
方法能够 转换 成功拒绝:
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-router 状态的解析器函数收到拒绝的承诺时,状态更改将中止。
更新
So I have my code like this ...
//ERRONEOUS resolve: { fn: function ($stateParams, myFactory) { myFactory.checkSession({viewId:99}) .then(function onSuccess(response) { var data = response.data; if (data.d == "Expired") { throw "Expired"; }
I can't understand why the throw doesn't trigger the $stateChangeError.
解析器功能需要return对路由器的承诺:
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
语句时,函数 return 的值为 undefined
。在这种情况下,路由器认为它是成功的,值为 undefined
.
还有.catch
方法是错误的
//ERRONEOUS }) .catch(function (response) { //e.preventDefault(); });
当 .catch
方法的拒绝处理程序省略 return
(或 throw
)语句时,函数 return 的值为 undefined
。这将 将拒绝转换为 成功的承诺,该承诺的解析值为 undefined
。
//CORRECT
})
.catch(function (response) {
//THROW to chain rejection
throw response;
//e.preventDefault();
});
函数式编程的经验法则是——总是return某事。
在承诺成功和拒绝的情况下:总是 return
或 throw
某事。