2

在我的單頁應用程序中,我需要保留狀態歷史記錄,以便在狀態之間來回導航。我有我自己的前進和後退按鈕,我在我的頁面上使用,而不是通過瀏覽器的按鈕。管理UI路由器狀態歷史記錄

這是下面的代碼,我使用了我創建的服務來存儲數組中的狀態。

$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返回到B - B被再次添加

這導致從b到c到b到c的無限循環...因此,我基本上不需要允許先前的項目被添加到歷史中或以某種方式知道它將回到歷史中,而是stateChangeStart不允許有任何區別。

幫助!

回答

1

在服務中,我最終添加了一個goBack方法,當想要遍歷歷史記錄時會調用它。該功能設置一個標誌,指示在歷史中移回。然後,當stateChangeStart事件被觸發並添加到數組時,服務知道它是一個不需要添加的項目,重置該標誌並返回。到目前爲止,它運作良好。

0

你可以通過驗證歷史(長度-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; 
    } 
    .... 
} 
+0

在我目前的應用程序中,只需使用不同的參數就可以處於相同的狀態。例如, /page/2 /page/3 所以'page'是狀態,2和3是參數。所以它必須比較狀態和參數,這似乎是不必要的。 – whatsTheDiff

+0

如果您只希望historyItem推入歷史記錄,如果先前狀態與當前狀態不相等,則可以在$ stateChangeStart函數作用域上添加驗證。 $ rootScope.on('$ stateChangeStart',function(event,toState,toParams,fromState){ if(toState === fromState){ return; } – mtamma