我正在使用angular-ui-router' resolve
从服务器获取数据,然后再转移到州。有时,对服务器的请求失败,我需要通知用户有关失败的信息。如果我从控制器呼叫服务器,我可以放then
并在呼叫失败的情况下调用我的通知服务。我将调用放在resolve
中的服务器上,因为我希望后代状态在服务器启动之前等待服务器的结果。
如果对服务器的调用失败,我在哪里可以捕获错误? (我已阅读documentation,但仍不确定如何。另外,我正在寻找尝试使用此新代码段工具的理由:)。
"use strict";
angular.module('MyApp', ["ui.router"]).config([
"$stateProvider",
"$urlRouterProvider",
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/item");
$stateProvider
.state("list", {
url: "/item",
template: '<div>{{listvm}}</div>' +
'<a ui-sref="list.detail({id:8})">go to child state and trigger resolve</a>' +
'<ui-view />',
controller: ["$scope", "$state", function($scope, $state){
$scope.listvm = { state: $state.current.name };
}]
})
.state("list.detail", {
url: "/{id}",
template: '<div>{{detailvm}}</div>',
resolve: {
data: ["$q", "$timeout", function ($q, $timeout) {
var deferred = $q.defer();
$timeout(function () {
//deferred.resolve("successful");
deferred.reject("fail"); // resolve fails here
}, 2000);
return deferred.promise;
}]
},
controller: ["$scope", "data", "$state", function ($scope, data, $state) {
$scope.detailvm = {
state: $state.current.name,
data: data
};
}]
});
}
]);
&#13;
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
<div ng-app="MyApp">
<ui-view />
</div>
&#13;
答案 0 :(得分:74)
老问题,但我遇到了同样的问题,在ui-router的常见问题解答部分偶然发现了这个问题
如果您遇到的问题是没有发现琐碎的错误 因为它发生在一个州的解决功能中,这个 实际上是规范中承诺的预期行为。
因此,您可以在此应用的运行阶段捕获所有解决错误
$rootScope.$on('$stateChangeError',
function(event, toState, toParams, fromState, fromParams, error){
// this is required if you want to prevent the $UrlRouter reverting the URL to the previous valid location
event.preventDefault();
...
})
答案 1 :(得分:22)
问题是,如果路由解析中的任何依赖项被拒绝,则控制器 将不会 被实例化。因此,您可以将故障转换为可在实例化控制器中检测到的数据。
示例伪代码: -
data: ["$q", "$timeout","$http", function ($q, $timeout, $http) {
return $timeout(function () { //timeout already returns a promise
//return "Yes";
//return success of failure
return success ? {status:true, data:data} : {status:false}; //return a status from here
}, 2000);
}]
并在您的控制器中: -
controller: ["$scope", "data", "$state", function ($scope, data, $state) {
//If it has failed
if(!data.status){
$scope.error = "Some error";
return;
}
$scope.detailvm = {
state: $state.current.name,
data: data
};
如果您正在进行$http
调用或类似调用,即使发生故障也可以使用http promise来解析数据并将状态返回给控制器。
实施例: -
resolve: {
data: ["$q", "$timeout","$http", function ($q, $timeout, $http) {
return $http.get("someurl")
.then(function(){ return {status:true , data: "Yes"} },
function(){ return {status:false} }); //In case of failure catch it and return a valid data inorder for the controller to get instantated
}]
},
"use strict";
angular.module('MyApp', ["ui.router"]).config([
"$stateProvider",
"$urlRouterProvider",
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/item");
$stateProvider
.state("list", {
url: "/item",
template: '<div>{{error}}</div><div>{{listvm}}</div>' +
'<a ui-sref="list.detail({id:8})">go to child state and trigger resolve</a>' +
'<ui-view />',
controller: ["$scope", "$state", function($scope, $state){
$scope.listvm = { state: $state.current.name };
}]
})
.state("list.detail", {
url: "/{id}",
template: '<div>{{detailvm}}</div>',
resolve: {
data: ["$q", "$timeout","$http", function ($q, $timeout, $http) {
return $http.get("/").then(function(){ return {status:true , data: "Yes"} }, function(){ return {status:false} })
}]
},
controller: ["$scope", "data", "$state", function ($scope, data, $state) {
$scope.detailvm = {
state: $state.current.name,
data: data.status ? data :"OOPS Error"
};
}]
});
}
]);
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<script data-require="angular-ui-router@*" data-semver="0.2.10" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<div ng-app="MyApp">
<ui-view></ui-view>
</div>