AngularJS 1.5.0带来了$resolve属性,旨在使ngRoute解析数据更容易传递到视图中,而无需为指令创建控制器.此属性也适用于常规视图.这样可行:
(function() { function ConfigureRoutes($routeProvider) { $routeProvider. when('/test',{ templateUrl: 'test.html',controller: 'TestController',controllerAs: 'vm',resolve: { 'stuff': ['$q',function($q) { return $q.when([ { id: 1,name: 'John' },{ id: 2,name: 'Jake' } ]); }] }); } app.config(['$routeProvider',ConfigureRoutes]); })(); <pre>{{ $resolve.stuff | json }}</pre>
但是,有些时候我有几个解析函数,我想在视图中使用之前传递给控制器进行变异.目前我做的事情如下:
when('/test',{ ... resolve: { 'stuff_1': ... 'stuff_2': ... } }); app.controller('StuffController',['stuff_1','stuff_2',function(stuff_1,stuff_2) { this.stuff_1 = stuff_1; this.stuff_2 = stuff_2; }]);
有没有办法访问这个新的$resolve属性而无需单独访问这些参数?我试过了:
app.controller('StuffController',['$scope',function($scope) { this.stuff_1 = $scope.$resolve.stuff_1; // $scope.$resolve == undefined }]); app.controller('StuffController',['$resolve',function($resolve) { this.stuff_1 = $resolve.stuff_1; // injector error }]);
编辑:
对于那些将来可能会发现这种情况的人,您可以在控制器中以不同的方式访问此$resolve对象:
app.controller('TestController',function($route) { this.$resolve = $route.current.locals; });
因此决定在实例化控制器之前不附加$resolve.
决定也不做出决定和注射.这可以使用$q.all()作为单个解析函数来实现,如下所示:
function config($routeProvider) { $routeProvider.when('/',template: 'test.html',resolve: { $resolve: function($q) { return $q.all({ local_1: $q.when(),local_2: $q.when() }); } }); }
或者如果你想要一个分叉版本,请参阅PR
($scope.$在控制器之前解析)[https://github.com/angular/angular.js/pull/14135]
($resolve as injectable)
[https://github.com/angular/angular.js/pull/14136]
解决方法
在调用控制器和将$resolve属性放在范围之间显然存在延迟.
angular.module("myApp").controller("test",function($scope,$timeout) { var vm = $scope; console.log("test controller") //console.log(vm); console.log("$resolve=",$scope.$resolve); //Undefined $timeout(function() { console.log("timeout $resolve"); console.log("$resolve=",$scope.$resolve); //Defined }); });
使用$timeout,值将解析.
$watch的示例
angular.module("myApp").controller("test",function($scope) { var vm = $scope; console.log("test controller") console.log(vm); console.log("$resolve=",$scope.$resolve); //Undefined $scope.$watch("$resolve",function(value) { console.log("watch $resolve"); console.log(value); //Defined }); });
使用$watch,值会解析.
审查源代码
在ngView.js Line #273中,控制器被实例化.
在ngView.js Line #280中,$resolve属性放在范围内.
这是一个错误.在实例化控制器之前,没有理由不将$resolve属性放在作用域上.
来自GitHub:
feat(ngView):引用范围#13400中已解析的本地化
路线的所有结算现在都附加到路线的本地范围,
作为名称由resolveAs属性给出的属性
路线定义.
如果未指定resolveAs,则默认为$resolve.
通过能够引用所有内容,这将更容易使用ngRoute
路由的解析值,直接在范围上,而不是具有
实现控制器只是手动复制解决方案.
例如,而不是
$routeProvider.when('/',{ resolve: { item1: ($http) => $http.get(...),item2: ($http) => $http.get(...) },template: '<my-app item1="vm.item1" item2="vm.item2"></my-app>',controller: ['item1','item2',function(item1,item2) { this.item1 = item1; this.item2 = item2; }] });
现在可以做了
$routeProvider.when('/',template: '<my-app item1="$resolve.item1" item2="$resolve.item2"></my-app>' });