What's the correct way to update a ui-router view when state parameters change?
当状态参数发生变化时,更新ui-router视图的正确方法是什么?
For example, if I've got a state like:
例如,如果我有一个状态:
.state("page.view", {
url: "/pages/:slug",
views: {
"": {
controller: "PageCtrl",
templateUrl: "page-view.html",
},
},
})
And an (incorrect) controller which looks like this:
和一个(不正确的)控制器看起来像这样:
.controller("PageCtrl", function($scope, $state) {
$scope.page = loadPageFromSlug($state.params.slug);
})
How can I correctly load a new $scope.page
when the $state.slug
changes?
当$ state.slug更改时,如何正确加载新的$ scope.page?
Note that the above does not work when moving from page to another because the controller is only run once, when the first page loads.
请注意,当从页面移动到另一页时,上述操作无效,因为控制器仅在第一页加载时运行一次。
3 个解决方案
#1
10
I would do something like this:
我会做这样的事情:
.controller("PageCtrl", function($scope, $state) {
$scope.$on("$stateChangeSuccess", function updatePage() {
$scope.page = $state.params.slug;
});
});
I'd be curious if you find a better way - there may be some way to just watch the value of the state slug, but this is clean and clearly articulates what it is that you're watching for.
如果你找到一个更好的方法我会很好奇 - 可能有一些方法可以只看到状态slug的价值,但这很干净,清楚地表达了你正在观察的是什么。
#2
2
I am really not fully sure, if I do not miss something here - but, based on the snippets shown in your question:
我真的不完全确定,如果我不想错过这里 - 但是,根据你问题中显示的片段:
-
PageCtrl
is related to state "page.view" and will be run as many times as "page.view" state is triggered -
"page.view"
state has declared param slug -url: "/pages/:slug",
, which will trigger state change - whenever it is changed - If the above is true (if I do not oversee something) we can use stateConfig setting - resolve
- there is no need to use
$state.params
. We can use$stateParams
(more UI-Router way I'd personally say)
PageCtrl与状态“page.view”相关,并且会在触发“page.view”状态时运行多次
“page.view”状态已声明param slug - url:“/ pages /:slug”,它将触发状态更改 - 无论何时更改
如果上述情况属实(如果我不监督某些事情),我们可以使用stateConfig设置 - 解决
没有必要使用$ state.params。我们可以使用$ stateParams(我个人说的更多UI-Router方式)
Well if all that is correct, as shown in this working plunker, we can do it like this
好吧,如果所有这些都是正确的,如这个工作的plunker所示,我们可以这样做
resolver:
var slugResolver = ['$stateParams', '$http'
, function resolveSlug($stateParams, $http){
return $http
.get("slugs.json")
.then(function(response){
var index = $stateParams.slug;
return response.data[index];
});
}];
Adjusted state def:
调整后的状态def:
.state("page.view", {
url: "/pages/:slug",
views: {
"": {
controller: "PageCtrl",
templateUrl: "page-view.html",
resolve: { slug : slugResolver },
},
},
})
And the PageCtrl:
和PageCtrl:
.controller('PageCtrl', function($scope,slug) {
$scope.slug = slug;
})
Check it all in action here
在这里检查一切
#3
1
I had this problem in ui-router 0.2.14. After upgrading to 0.2.18 a parameter change does fire the expected $stateChange*
events.
我在ui-router 0.2.14中遇到了这个问题。升级到0.2.18后,参数更改会触发预期的$ stateChange *事件。
#1
10
I would do something like this:
我会做这样的事情:
.controller("PageCtrl", function($scope, $state) {
$scope.$on("$stateChangeSuccess", function updatePage() {
$scope.page = $state.params.slug;
});
});
I'd be curious if you find a better way - there may be some way to just watch the value of the state slug, but this is clean and clearly articulates what it is that you're watching for.
如果你找到一个更好的方法我会很好奇 - 可能有一些方法可以只看到状态slug的价值,但这很干净,清楚地表达了你正在观察的是什么。
#2
2
I am really not fully sure, if I do not miss something here - but, based on the snippets shown in your question:
我真的不完全确定,如果我不想错过这里 - 但是,根据你问题中显示的片段:
-
PageCtrl
is related to state "page.view" and will be run as many times as "page.view" state is triggered -
"page.view"
state has declared param slug -url: "/pages/:slug",
, which will trigger state change - whenever it is changed - If the above is true (if I do not oversee something) we can use stateConfig setting - resolve
- there is no need to use
$state.params
. We can use$stateParams
(more UI-Router way I'd personally say)
PageCtrl与状态“page.view”相关,并且会在触发“page.view”状态时运行多次
“page.view”状态已声明param slug - url:“/ pages /:slug”,它将触发状态更改 - 无论何时更改
如果上述情况属实(如果我不监督某些事情),我们可以使用stateConfig设置 - 解决
没有必要使用$ state.params。我们可以使用$ stateParams(我个人说的更多UI-Router方式)
Well if all that is correct, as shown in this working plunker, we can do it like this
好吧,如果所有这些都是正确的,如这个工作的plunker所示,我们可以这样做
resolver:
var slugResolver = ['$stateParams', '$http'
, function resolveSlug($stateParams, $http){
return $http
.get("slugs.json")
.then(function(response){
var index = $stateParams.slug;
return response.data[index];
});
}];
Adjusted state def:
调整后的状态def:
.state("page.view", {
url: "/pages/:slug",
views: {
"": {
controller: "PageCtrl",
templateUrl: "page-view.html",
resolve: { slug : slugResolver },
},
},
})
And the PageCtrl:
和PageCtrl:
.controller('PageCtrl', function($scope,slug) {
$scope.slug = slug;
})
Check it all in action here
在这里检查一切
#3
1
I had this problem in ui-router 0.2.14. After upgrading to 0.2.18 a parameter change does fire the expected $stateChange*
events.
我在ui-router 0.2.14中遇到了这个问题。升级到0.2.18后,参数更改会触发预期的$ stateChange *事件。