Javascript 如何将浏览器上的可选状态参数保留回ui路由器?

Javascript 如何将浏览器上的可选状态参数保留回ui路由器?,javascript,angularjs,angular-ui-router,angular-ui,angularjs-routing,Javascript,Angularjs,Angular Ui Router,Angular Ui,Angularjs Routing,我有一个父状态,其中有两个子状态,我将根据URL显示一个状态 在这两个状态中有一个必须使用参数,如param1和param2,我在状态定义中使用了ui路由器的params选项 状态 $stateProvider.state('tabs.account', { url: '/account', views: { 'content@tabs': { templateUrl: 'account.html', control

我有一个父状态,其中有两个子状态,我将根据
URL
显示一个状态

在这两个
状态中
有一个必须使用参数,如
param1
param2
,我在状态定义中使用了ui路由器的
params
选项

状态

$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
    }
});
如果你看一下我的路线,params选项并没有真正引入
URL
,这就是为什么我认为它是可选的

问题 看看plunkr,我已经显示了两个选项卡账户调查

  • 单击测量选项卡,然后在显示的
    文本区域中添加一些数据
    
  • 单击转到帐户,将这些
    文本区域
    值传递给 通过在锚上执行
    ui sref=“tabs.Account({param1:thing1,param2:thing2})”
    来创建另一个Account选项卡

  • 现在,您将在html上看到
    param1
    param2
    值,该值已从
    $stateparms

  • 现在再次单击调查选项卡,您将进入调查页面
  • 只需单击browser back(浏览器返回),您就会注意到
    param
    值没有得到
    null
  • 我相信你已经明白我想问的,为什么可选参数值没有被存储?因为他们一直是国家的一部分

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

    • 通过创建一个在两个视图之间共享数据的服务
    • 通过在状态URL内添加参数。像
      url:'/account/:param1/:param2',
      (但我不喜欢这样)
    我已经尝试过角度ui路由器,但似乎对我不起作用。更好的方法是什么

    是否有任何方法可以使我的用例工作,任何想法都将不胜感激


    Github

    我相信,如果不使用您提供的两种解决方案之一,您想要实现的目标是不可能的

    浏览器后退按钮只是保留URL历史记录。他对ui路由器的内部状态一无所知,只会强制更改URL

    强制更改URL将触发内部ui路由器机器,但不幸的是,ui路由器将看到URL更改,就像有人手动更改URL一样

    Ui路由器将对URL指向的路由触发新的路由更改。这意味着他不知道您想“返回”,只会将状态更改为新状态,而不带任何参数

    摘要

    单击“上一步”按钮将根据URL将状态更改为新状态,而不是返回到以前的状态

    这就是为什么将参数添加到URL可以解决问题的原因。因为URL是歧视性的,所以你最终会到达你想要的州


    希望有帮助

    一个解决方案是缓存状态参数,并在进入
    选项卡时有条件地加载它们。account
    状态。UI路由器状态配置实际上允许您为这些类型的“进入状态时做点什么”情况提供一个
    oneter
    回调

    以下是用作缓存的基本逻辑,以及可用的Plunker:

    • 当您进入
      选项卡.account
      状态时,请检查您的状态参数
      • 如果有,请将它们缓存到本地存储
      • 如果没有,请将它们从本地存储加载到
        $stateParams
    下面是一个示例代码片段供参考(取自Plunker):

    $stateProvider.state('tabs.account'{
    ...
    onEnter:['$stateparms','$window',函数($stateparms,$window){
    如果($stateParams.param1){
    $window.localStorage.setItem('tabs.account.param1',$stateparms.param1);
    }否则{
    $stateParams.param1=$window.localStorage.getItem('tabs.account.param1');
    }
    如果($stateParams.param2){
    $window.localStorage.setItem('tabs.account.param2',$stateparms.param2);
    }否则{
    $stateParams.param2=$window.localStorage.getItem('tabs.account.param2');
    }
    }],
    ...
    
    }
    我会将
    参数定义移动到父状态,以便在两个子状态之间共享可选的状态参数

    子状态将从父状态继承
    $stateParams
    ,因此不需要真正的“变通方法”

    只需像往常一样在子控制器中插入
    $stateParams
    ,您就可以完全访问传递的参数。如果您不想在特定子状态中使用这些参数,只需避免注入它们

    这与

    • 后退按钮
    • 前进按钮
    • ui sref(无参数(将保持原样))
    • ui sref(带参数(将覆盖))

    如果在
    父级
    的状态树中运行时,您想清除参数,则必须手动执行此操作

    这将是我使用此解决方案所能看到的唯一真正的警告

    我意识到,在您提出的情况下,手动清理可能不可取,但您没有采取积极的立场反对它,因此我认为该建议有价值

    对我来说,这听起来像是。有一些建议的方法可以使状态参数持久化,而问题就出在这个表面之外

    根据问题的定义,有一些数据应该独立于状态进行保存。因此,相对于状态而言,它是一种全局性的。因此,应该有一个服务来保存它,并且两个状态的控制器根据需要对其进行维护。只是不要在状态参数中传递超出一个状态范围的数据

    粘性状态很容易适应这种方法
    $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 }
        }
      })