在控制器而不是视图中访问 Angular 路由范围 属性 $resolve
Access Angular route scope property $resolve within controller instead of view
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
。
还决定不制造 $resolve
和注射剂。这可以使用 $q.all()
作为单个解析函数来实现,如下所示:
function config($routeProvider) {
$routeProvider.when('/',
controller: 'TestController',
controllerAs: 'vm',
template: 'test.html',
resolve: {
$resolve: function($q) {
return $q.all({
local_1: $q.when(),
local_2: $q.when()
});
}
});
}
或者,如果您想要一个分叉版本,请参阅 PR
($scope.$resolve before controller)[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>',
controllerAs: 'vm',
controller: ['item1', 'item2', function(item1, item2) {
this.item1 = item1;
this.item2 = item2;
}]
});
现在可以做到了
$routeProvider.when('/', {
resolve: {
item1: ($http) => $http.get(...),
item2: ($http) => $http.get(...)
},
template: '<my-app item1="$resolve.item1" item2="$resolve.item2"></my-app>'
});
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
。
还决定不制造 $resolve
和注射剂。这可以使用 $q.all()
作为单个解析函数来实现,如下所示:
function config($routeProvider) {
$routeProvider.when('/',
controller: 'TestController',
controllerAs: 'vm',
template: 'test.html',
resolve: {
$resolve: function($q) {
return $q.all({
local_1: $q.when(),
local_2: $q.when()
});
}
});
}
或者,如果您想要一个分叉版本,请参阅 PR ($scope.$resolve before controller)[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>',
controllerAs: 'vm',
controller: ['item1', 'item2', function(item1, item2) {
this.item1 = item1;
this.item2 = item2;
}]
});
现在可以做到了
$routeProvider.when('/', {
resolve: {
item1: ($http) => $http.get(...),
item2: ($http) => $http.get(...)
},
template: '<my-app item1="$resolve.item1" item2="$resolve.item2"></my-app>'
});