【问题标题】:Manage ui-router state history管理 ui-router 状态历史
【发布时间】:2016-05-17 21:46:14
【问题描述】:

在我的单页应用程序中,我需要保留状态历史记录,以便更轻松地在状态之间来回导航。我有自己的前进和后退按钮,我在我的页面上使用,而不是通过浏览器的按钮。

这是我拥有的以下代码,它使用我创建的服务将状态存储在数组中。

$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
    StateMgmtService.add(toState, toParams);
});

在服务中,我有一些大意如下:

var history = [];

    return {
        previous: function () {
            if (history && history.length > 0) {
                return history[history.length - 1];
            }
        },
        add: function (state, params) {
            var historyItem = {
                state: state,
                parameters: params
            };

            history.push(historyItem);
        }
    };

问题是,每当我回到之前的状态时,stateChangeStart 都会被触发,这基本上会污染我的历史记录。考虑以下示例:

  • 从状态 a 开始到 b - b 被添加到历史记录中
  • b 到 c - c 被添加
  • c 返回 b - b 再次添加

这导致从 b 到 c 到 b 到 c 的无限循环......所以我基本上不需要允许将先前的项目添加到历史记录中,或者以某种方式知道它会回到历史记录中,但是stateChangeStart 不允许任何区分。

救命!

【问题讨论】:

    标签: javascript angularjs angular-ui-router single-page-application


    【解决方案1】:

    在服务中,我最终添加了一个 goBack 方法,当想要遍历历史记录时将调用该方法。此函数设置一个标志,指示在历史中向后移动。然后当 stateChangeStart 事件被触发并添加到数组中时,服务知道它是不需要添加的项目,重置标志,并从它返回。到目前为止效果很好。

    【讨论】:

      【解决方案2】:

      您可以通过验证历史(长度-2)与当前状态相等来解决它。 一些这样的代码,在服务上:

      add: function(state, params) {
        var isBackState = function (currentState, listState) {
          var listStateLength = listState.length;
          if (listState[listStateLength -2].state === currentState) {
            return true;
          }
      
          return false;
        };
      
        if (history.length > 1 && isBackState(state, history) {
          return;
        }
      
        var historyItem = {
          state: state,
          parameters: params
        };
      
        history.push(historyItem);
      }
      

      如果您只希望 historyItem 在先前状态与当前状态不相等的情况下推送到历史记录中,那么您可以在 $stateChangeStart 函数范围内添加验证。

      $rootScope.on('$stateChangeStart', function (event, toState, toParams, fromState) {
        if (toState === fromState) {
          return;
        }
        ....
      }
      

      【讨论】:

      • 在我当前的应用程序中,可以使用不同的参数处于相同的状态。例如 /page/2 /page/3 所以 'page' 是状态, 2 和 3 是参数。所以它必须比较状态和参数,这似乎有些不必要。
      • 如果您只希望 historyItem 在先前状态与当前状态不相等的情况下推送到历史记录中,那么您可以在 $stateChangeStart 函数范围内添加验证。 $rootScope.on('$stateChangeStart', function (event, toState, toParams, fromState) { if (toState === fromState) { return; }
      猜你喜欢
      • 1970-01-01
      • 2013-01-25
      • 2020-03-07
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 2015-05-23
      • 2018-08-07
      • 2016-07-05
      相关资源
      最近更新 更多