Angularjs 如何在路由刷新时将异步数据重新加载到控制器作用域?
我有一个服务功能,每次访问或刷新路线时都需要调用该功能。该函数返回一个角度承诺。每次调用函数时,都需要将承诺的结果加载到控制器的作用域中 我目前正在使用状态定义上的resolve参数来调用函数Angularjs 如何在路由刷新时将异步数据重新加载到控制器作用域?,angularjs,angular-ui-router,angular1.6,Angularjs,Angular Ui Router,Angular1.6,我有一个服务功能,每次访问或刷新路线时都需要调用该功能。该函数返回一个角度承诺。每次调用函数时,都需要将承诺的结果加载到控制器的作用域中 我目前正在使用状态定义上的resolve参数来调用函数 .state('app.theState', { url: '/theRoute/:theRouteId', views: { 'menuContent': { templateUrl: 'templates/theRoute.html', co
.state('app.theState', {
url: '/theRoute/:theRouteId',
views: {
'menuContent': {
templateUrl: 'templates/theRoute.html',
controller: 'TheRouteCtrl'
}
},
resolve: {theResolvedResult: function(theService){
return theService.theAsyncCall().then(function(result){
return result;
},function(errMsg){
return errMsg;
});}
})
数据作为参数传递到控制器中
.controller( 'TheRouteCtrl', function($scope, $state, $log, theResolvedResult)
我正在更新保存ResolvedResult的全局上的手表中的控制器$scope。(使用本章末尾描述的方法)。我试着观察争论本身,但从未被触发
$scope.$state=$state;
$scope.$watch('$state.$current.locals.globals.theResolvedResult', function (result) {
$scope.aValue = result.aValue;
});
不幸的是,我猜因为监视是全局的,所以当任何路由运行时都会触发监视,并且所有其他路由都会对每个路由抛出一个错误,但定义了解析的路由除外
ionic.bundle.js:26794 TypeError: Cannot read property 'aValue' of undefined
at route_ctrl.js:234
如何修复这些错误,或者有更好的方法吗?可能只是为了防止未定义
结果的情况:
$scope.$watch('$state.$current.locals.globals.theResolvedResult', function (result) {
if (result) {
$scope.aValue = result.aValue;
}
});
角度V1.6的中断更改
将初始化逻辑移到$onInit
功能中
依赖于存在绑定的初始化逻辑应该放在控制器的$onInit()
方法中,该方法保证在分配绑定后始终被调用
错误拒绝处理程序
解决方案是将被拒绝的承诺转换为已履行的承诺:
/* ERRONEOUS
resolve: {theResolvedResult: function(theService){
return theService.theAsyncCall().then(function(result){
return result;
},function(errMsg){
//ERRONEOUS converts rejection
return errMsg;
});}
*/
// BETTER
resolve: {
theResolvedResult: function(theService){
return theService.theAsyncCall().then(function(result){
console.log(result);
return result;
},function catchHandler(errMsg){
console.log(errMsg);
//return errMsg;
//IMPORTANT re-throw error
throw errMsg;
});
}
在catch处理程序中重新抛出错误是很重要的。否则,将拒绝的承诺转换为履行的承诺。这类似于在香草JavaScript中的工作方式
函数将函数作为其第一个参数:
/* HACKY
$scope.$state=$state;
$scope.$watch('$state.$current.locals.globals.theResolvedResult', function (result) {
$scope.aValue = result.aValue;
});
*/
//BETTER
//$scope.$state=$state;
//$scope.$watch('$state.$current.locals.globals.theResolvedResult',
$scope.$watch(
function () {
return $state.$current.locals.globals.theResolvedResult;
},
function (result) {
if (result) {
$scope.aValue = result.aValue;
};
});
当的第一个参数是字符串时,它将使用$scope
作为上下文对其进行求值。由于$state
服务不是$scope
的属性,因此应该使用函数。最好的办法是首先避免$watch
黑客攻击。在服务中,或者至少在解析中,应确保该值是正确的
查看resolve
应如何工作的演示
一般的想法是,resolve
有一个任务;确保数据在需要时准备就绪。关于ui.router
如何处理resolve
分辨率,有几个示例。它们有点有限,但通常显示出预期的“良好”结果。错误处理最终由您自己选择
享受吧 谢谢,这是一个很好的务实解决办法。我仍然希望得到一个只为当前控制器运行手表的解决方案,以消除浪费性的检查,并且在应该定义结果而不是定义结果时不隐藏错误。所以我将这个问题留待讨论。谢谢你的建议!
/* HACKY
$scope.$state=$state;
$scope.$watch('$state.$current.locals.globals.theResolvedResult', function (result) {
$scope.aValue = result.aValue;
});
*/
//BETTER
//$scope.$state=$state;
//$scope.$watch('$state.$current.locals.globals.theResolvedResult',
$scope.$watch(
function () {
return $state.$current.locals.globals.theResolvedResult;
},
function (result) {
if (result) {
$scope.aValue = result.aValue;
};
});