管理ui-router状态历史记录

时间:2016-05-17 21:46:15

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

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

以下代码我使用我创建的服务将状态存储在数组中。

$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不允许任何区别。

帮助!

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

您可以通过验证历史记录(长度为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;
  }
  ....
}