尝试迁移angularjs应用程序以使用新版本的angular-ui-router
1.0.14,并在尝试在解决状态时更改$stateParams
时偶然发现问题。
例如,之前(使用angular-ui-router
0.3.2时)修改$stateParams
的工作方式如下:
$stateProvider.state('myState', {
parent: 'baseState',
url: '/calendar?firstAvailableDate',
template: 'calendar.html',
controller: 'CalendarController',
controllerAs: 'calendarCtrl',
resolve: {
availableDates: ['CalendarService', '$stateParams', function(CalendarService, $stateParams) {
return CalendarService.getAvailableDates().then(function(response){
$stateParams.firstAvailableDate = response[0];
return response;
});
}]
}
})
问题是{1}}在解决后填充,我不知道如何在解析期间更新firstAvailableDate
时使用新版$transition$.params()
1.0.14。
我尝试过,并设法用
更新url参数触发angular-ui-router
但这会重新加载状态,因此屏幕闪烁
修改$state.go('myState', {firstAvailableDate : response[0]})
以实际覆盖参数。在查看$transition$.treeChanges().to[$transition$.treeChanges().length-1].paramValues.firstAvailableDate = response[0];
params()
上的实施后,我已经完成了这项工作。
尽管这些选项都有效,但它们似乎是黑客而不是书籍实施。
尝试修改解析中的参数时使用的正确方法是什么?
答案 0 :(得分:4)
请查看此文档:params.paramdeclaration#dynamic。也许这就是你要找的东西:...a transition still occurs...
。
当dynamic为true时,更改参数值不会导致输入/退出状态。不会重新获取结算,也不会重新加载视图。
通常,如果参数值发生变化,则声明将重新加载(输入/退出)参数的状态。当参数是动态的时,仍然会发生转换,但它不会导致状态退出/进入。
这可以用于构建UI,其中组件在param值更改时自动更新。这很有用的常见场景是搜索/分页/排序。
注意您无法在$stateProvider.state
内将此类逻辑纳入您的决心。我会通过使用dynamic
参数来防止状态重新加载。遗憾的是,当您尝试在解析部分内更新状态(例如,使用dynamic
)时,$stage.go()
规则不起作用。因此,我将该逻辑移动到控制器中以使其工作得很好 - DEMO PLNKR 。
由于userId
是动态参数,因此视图在更改时不会再次进入/退出。
$stateProvider.state('userlist.detail', {
url: '/:userId',
controller: 'userDetail',
controllerAs: '$ctrl',
params: {
userId: {
value: '',
dynamic: true
}
},
template: `
<h3>User {{ $ctrl.user.id }}</h3>
<h2>{{ $ctrl.user.name }} {{ !$ctrl.user.active ? "(Deactivated)" : "" }}</h2>
<table>
<tr><td>Address</td><td>{{ $ctrl.user.address }}</td></tr>
<tr><td>Phone</td><td>{{ $ctrl.user.phone }}</td></tr>
<tr><td>Email</td><td>{{ $ctrl.user.email }}</td></tr>
<tr><td>Company</td><td>{{ $ctrl.user.company }}</td></tr>
<tr><td>Age</td><td>{{ $ctrl.user.age }}</td></tr>
</table>
`
});
app.controller('userDetail', function ($transition$, $state, UserService, users) {
let $ctrl = this;
this.uiOnParamsChanged = (newParams) => {
console.log(newParams);
if (newParams.userId !== '') {
$ctrl.user = users.find(user => user.id == newParams.userId);
}
};
this.$onInit = function () {
console.log($transition$.params());
if ($transition$.params().userId === '') {
UserService.list().then(function (result) {
$state.go('userlist.detail', {userId: result[0].id});
});
}
}
});
$transition.on*
挂钩处理新的参数:另一种方法是在更改状态之前设置正确的state
参数。但你已经说过,这是你不想要的。如果我遇到同样的问题:在更改视图之前,我会尝试设置正确的state
参数。
app.run(function (
$transitions,
$state,
CalendarService
) {
$transitions.onStart({}, function(transition) {
if (transition.to().name === 'mySate' && transition.params().firstAvailableDate === '') {
// please check this, I don't know if a "abort" is necessary
transition.abort();
return CalendarService.getAvailableDates().then(function(response){
// Since firstAvailableDate is dynamic
// it should be handled as descript in the documents.
return $state.target('mySate', {firstAvailableDate : response[0]});
});
}
});
});
$transition.on*
挂钩处理新的参数
注意:在LAZY结算之前,redirectTo被处理为onStart挂钩。
这与标题“通过在路线更改开始时使用$transition.on*
挂钩处理新的参数”附近提供的内容相同,因为redirectTo
也是{{1自动处理的钩子。
onStart