AngularJS中resolve方法未向控制器返回数据问题排查
问题分析与解决方案
我来帮你拆解AngularJS路由resolve和控制器结合时遇到的这两个典型问题:
问题1:移除controller和controllerAs后出现Unknown provider错误
原因
路由配置里的resolve依赖仅对由路由实例化的控制器生效。如果你移除路由中的controller配置,改用模板里的ng-controller声明控制器,这个控制器是由Angular的$controller服务直接创建的,完全不知道路由里定义的getposts依赖,自然会抛出找不到提供者的错误。
解决办法
要使用路由resolve的特性,就必须让路由负责控制器的实例化——也就是不能移除路由里的controller和controllerAs配置,同时模板里不能再加ng-controller指令。
问题2:使用controllerAs时vm.posts无法在视图显示
原因
你犯了两个小错误:
- 依赖注入顺序错误:控制器的依赖数组里没把
getposts加进去,Angular无法识别这个依赖; - 模板访问方式错误:用了
controllerAs: "contactCtrl"后,控制器实例会绑定到作用域的contactCtrl属性上,模板里必须通过contactCtrl.posts访问,而不是直接写posts; - 控制器里的
vm没加var,会变成全局变量,属于潜在的代码隐患。
修正后的完整代码
路由与控制器部分
var app = angular.module('simpleApp', ['ngRoute', 'ngSanitize']); app.config(['$routeProvider', function($routeProvider){ $routeProvider .when('/', { templateUrl: './partials/home.html' }) .when('/contact', { controller: "contactController", controllerAs: "contactCtrl", templateUrl: './partials/contact.html', resolve:{ getposts: function($http) { return $http.get('https://jsonplaceholder.typicode.com/comments/1') .then(function(response) { return response.data; }) } } }) }]) .controller('contactController', ['$scope', '$http', 'getposts', // 把getposts加入依赖数组 function($scope, $http, getposts){ var vm = this; // 加上var,避免全局变量 console.log(getposts); // 现在能正常拿到resolve返回的数据了 vm.posts = getposts; }])
contact.html模板部分
<div> <div class="row"> dfgdfg <div class="col-lg-6"> {{ contactCtrl.posts }} <!-- 通过controllerAs的别名访问数据 --> </div> </div> </div>
额外小提示
- AngularJS的依赖注入必须保证依赖数组和函数参数的顺序完全一致,否则会出现注入错误;
- 使用
controllerAs模式时,尽量减少$scope的使用,保持代码风格统一,更利于后续维护; - 如果觉得模板里写
contactCtrl.xxx太繁琐,可以在路由里添加bindToController: true(AngularJS 1.3+支持),不过上面的写法已经足够解决你的问题了。
内容的提问来源于stack exchange,提问作者rahul
相关产品推荐
相关产品推荐

