Angularjs ui路由器1.x.x在解析期间更改$transition$.params()

Angularjs ui路由器1.x.x在解析期间更改$transition$.params(),angularjs,angular-ui-router,Angularjs,Angular Ui Router,尝试迁移angularjs应用程序以使用新版的AngularUI router1.0.14,在解决状态时尝试更改$stateParams时遇到问题 例如,以前(使用angular ui router0.3.2时)修改$stateParams的工作方式如下: $stateProvider.state('myState', { parent: 'baseState', url: '/calendar?firstAvailableDate', template: 'calendar

尝试迁移angularjs应用程序以使用新版的
AngularUI 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;
       });
     }]
   }
 })
问题是在解析后填充了
firstAvailableDate
,我不知道在使用新版
angular ui router
1.0.14解析期间如何更新
$transition$.params()

我已经尝试过,并设法用更新url参数

  • 触发一个
    $state.go('myState',{firstAvailableDate:response[0]})
    ,但这会重新加载状态,因此屏幕会闪烁

  • $transition$.treeChanges()修改为[$transition$.treeChanges().length-1].paramValues.firstAvailableDate=response[0]
    以实际覆盖参数。在查看了
    $transition$
    params()
    上的实现之后,我完成了这项工作

  • 尽管这两个选项都有效,但它们似乎是黑客行为,而不是照本宣科的实现

    尝试修改解析中的参数时,正确的方法是什么?

    使用动态参数的方法: 请查看此文档:。也许这就是你想要的:
    …仍然会发生转换…

    当dynamic为true时,对参数值的更改不会导致进入/退出状态。将不会重新获取解析,也不会重新加载视图

    通常,如果参数值发生更改,则表示将重新加载(输入/退出)该参数的状态。当参数是动态的时,仍然会发生转换,但不会导致状态退出/进入

    这对于构建UI非常有用,在该UI中,当参数值更改时组件会自动更新。搜索/分页/排序是一个常用的场景

    注意您无法在
    $stateProvider.state
    中将此类逻辑放入解析中。我会使用
    动态
    参数来防止状态重新加载。不幸的是,
    动态
    规则在您尝试更新解析部件内的状态(例如,通过使用
    $stage.go()
    )时不起作用。因此,我将该逻辑移到控制器中,使其工作良好-

    由于
    userId
    是一个动态参数,因此在更改视图时不会再次进入/退出该视图

    定义动态参数:
    使用
    $transition处理新参数。在*
    上,路线更改开始时挂钩: 另一种方法是在更改为您的状态之前设置正确的
    状态
    参数。但你已经说过,这是你不想要的。如果我会面临同样的问题:我会在更改视图之前尝试设置正确的
    状态
    参数

    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*
    hooks on route change start via处理新参数 注意:在惰性解析之前,redirectTo作为onStart钩子处理

    这与上面标题“使用
    $transition.on*
    hooks on route change start
    处理新参数”附近提供的操作相同,因为
    重定向到
    也是一个具有自动处理功能的
    onStart
    钩子

    $stateProvider.state('myState', {
        parent: 'baseState',
        url: '/calendar?firstAvailableDate',
        template: 'calendar.html',
        controller: 'CalendarController',
        controllerAs: 'calendarCtrl',
        redirectTo: (trans) => {
            if (trans.params().firstAvailableDate === '') {
                var CalendarService = trans.injector().get('CalendarService');
                return CalendarService.getAvailableDates().then(function(response){
                    return { state: 'myState', params: { firstAvailableDate: response[0] }};
                });
            }
        }
    });
    

    能否创建一个包含您的
    $transition$
    部分的plnkr?首先
    $stateChangeStart
    在此版本的ui.router>=1()中实际上不存在。第二点是我想更新状态定义中的状态参数,而不是在全局运行中。@rave有任何反馈吗?不,这不是我想要的答案。我仍然希望重新蚀刻解析并重新加载视图。通过在状态定义中使用
    重定向到
    ,我找到了我的解决方案。@rave yes。你也可以这样做。请注意,
    redirectTo
    只不过是一个
    onStart
    hook->。这样,
    redirectTo
    做的事情和我在这个答案的第二种方法中做的一样,对吗?
    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]});
                });
            }
        });
    });
    
    $stateProvider.state('myState', {
        parent: 'baseState',
        url: '/calendar?firstAvailableDate',
        template: 'calendar.html',
        controller: 'CalendarController',
        controllerAs: 'calendarCtrl',
        redirectTo: (trans) => {
            if (trans.params().firstAvailableDate === '') {
                var CalendarService = trans.injector().get('CalendarService');
                return CalendarService.getAvailableDates().then(function(response){
                    return { state: 'myState', params: { firstAvailableDate: response[0] }};
                });
            }
        }
    });