如何在ui-router中保留浏览器上的可选状态参数?

Pan*_*kar 29 javascript angularjs angular-ui angularjs-routing angular-ui-router

我有一个父州,里面有两个孩子的州,我将根据这个州显示一个州URL.

在这两个中有states一个像param1和的参数param2,我params在状态定义中使用了ui-router选项.

$stateProvider.state('tabs.account', {
    url: '/account',
    views: {
        'content@tabs': {
            templateUrl: 'account.html',
            controller: function($scope, $stateParams) {
                //This params are internally used to make ajax and show some data.
                $scope.param1 = $stateParams.param1;
                $scope.param2 = $stateParams.param2;
            },
        }
    },
    params: {
        param1: { value: null }, //this are optional param
        param2: { value: null } //because they are not used in url
    }
});
Run Code Online (Sandbox Code Playgroud)

如果你看看我的路线,params选项并没有真正引入其中URL,这就是为什么我当时认为是可选的.

问题

看看plunkr,我已经显示了两个标签Account&Survey,

  1. 单击Survey选项卡,然后添加显示的数据textarea.
  2. 单击转到帐户,将通过锚点将这些textarea值传递到其他帐户选项卡ui-sref="tabs.account({param1: thing1, param2: thing2})"

  3. 现在,您将看到已分配给范围的html上的param1&param2$stateParams

  4. 现在再次点击Survey选项卡,您将登陆调查页面.
  5. 只需单击浏览器返回,您就会注意到param值没有得到null.

问题Plunkr

我相信你有我想问的问题,为什么可选参数值没有存储?因为他们是国家的一部分.

我知道我可以通过以下两种解决方案来解决这个问题.

  • 通过创建一个将在两个视图之间共享数据的服务.
  • 通过在状态URL中添加参数.喜欢url: '/account/:param1/:param2',(但我不喜欢这个)

我已经尝试过angular-ui-routers,sticky states但这似乎对我不起作用.有什么更好的方法呢?

有什么方法可以使我的用例工作,任何想法都会很感激.

Github 问题链接在这里

Kas*_*wau 21

我会将params定义移动到父状态,以便在两个子状态之间共享可选的状态参数.

子州将继承$stateParams您的父母,因此不需要真正的"解决方法".

只需$stateParams按照常规注入您的孩子控制器,您就可以完全访问被传递的参数.如果您不想在特定的子状态下使用params,只需避免注入它们.

这适用于;

  • 返回键
  • 前进按钮
  • ui-sref (没有参数(将保持原样))
  • ui-sref (用params(将覆盖))

$stateProvider
  .state('parent', {
    params: { p1: null, p2: null }
  })
  .state('parent.childOne', {
    url: '/one',
    controller: function ($stateParams) {
      console.log($stateParams); // { p1: null, p2: null }
    }
  })
  .state('parent.childTwo', {
    url: '/two',
    controller: function ($stateParams) {
      console.log($stateParams); // { p1: null, p2: null }
    }
  })
Run Code Online (Sandbox Code Playgroud)

如果你想在状态树中旅行时想要清除参数parent,你必须手动完成.

这将是我通过使用此解决方案可以看到的唯一真实警告.

我知道在你出席的情况下手动清算可能并不理想,但你没有采取积极的立场反对它,因此我觉得这个建议是有价值的.

更新的plunker


Chr*_*ang 7

一种解决方法是缓存状态参数并在进入tabs.account状态时有条件地加载它们.UI路由器状态配置实际上允许您onEnter为这些类型的"在进入状态时执行某些操作"情况提供回调.

这是使用localStorage作为缓存的基本逻辑,在这里使用Plunker :

  • 进入tabs.account州后,检查州的参数
    • 如果有,请将它们缓存到本地存储
    • 如果不这样做,请将它们从本地存储装入 $stateParams

这是一个示例代码片段供参考(取自Plunker):

  $stateProvider.state('tabs.account', {
    ...
    onEnter: ['$stateParams', '$window', function($stateParams, $window) {
      if($stateParams.param1) {
        $window.localStorage.setItem('tabs.account.param1', $stateParams.param1);
      } else {
        $stateParams.param1 = $window.localStorage.getItem('tabs.account.param1');
      }
      if($stateParams.param2) {
        $window.localStorage.setItem('tabs.account.param2', $stateParams.param2);
      } else {
        $stateParams.param2 = $window.localStorage.getItem('tabs.account.param2');
      }
    }],
    ...
  }
Run Code Online (Sandbox Code Playgroud)

一个需要注意的是,你的PARAMS将无限期持续(例如跨刷新和会话).为了解决这个问题,您可以清除应用程序负载上的缓存app.run.

最后一点是在Plunker中,我直接访问本地存储(通过Angular $window服务).您可能想要使用一些AngularJS模块 - 我在生产中使用了角度局部存储.