2015-07-12 29 views
5

我做了一個小實驗:http://codepen.io/hawkphil/pen/NqMomm?editors=101

這裏是我的狀態流量(點擊按鈕):Home -> Fact1 -> Fact2 -> Fact3 -> Fact2

在每個狀態變化,我我在console.log中顯示爲$ionicHistory.backView 但是,您可以在pen.js:64行中看到奇怪的事情發生。 $ionicHistory.backView「認爲」我從後退按鈕到app.fact2,並且它顯示app.fact1作爲之前的狀態(行pen.js:53)。這是不正確的,對吧?它應該顯示app.fact3作爲之前的狀態,因爲我通過單擊按鈕進入app.fact2狀態MANUALLY。我還展示了$timeout(行pen.js:59)的值,以防萬一。但它仍然不正確。

pen.js:56 stateChangeSuccess 
pen.js:64 State change from: tabs.home to: tabs.fact1 
pen.js:52 $scope.$watch $ionicHistory.backView change detect. newVal: 
pen.js:53 tabs.home 
pen.js:58 $timeout after 2 sec $ionicHistory.backView().stateName 
pen.js:59 tabs.home 
pen.js:56 stateChangeSuccess 
pen.js:64 State change from: tabs.fact1 to: tabs.fact2 
pen.js:52 $scope.$watch $ionicHistory.backView change detect. newVal: 
pen.js:53 tabs.fact1 
pen.js:58 $timeout after 2 sec $ionicHistory.backView().stateName 
pen.js:59 tabs.fact1 
pen.js:56 stateChangeSuccess 
pen.js:64 State change from: tabs.fact2 to: tabs.fact3 
pen.js:52 $scope.$watch $ionicHistory.backView change detect. newVal: 
pen.js:53 tabs.fact2 
pen.js:58 $timeout after 2 sec $ionicHistory.backView().stateName 
pen.js:59 tabs.fact2 
pen.js:56 stateChangeSuccess 
pen.js:64 State change from: tabs.fact3 to: tabs.fact2 
pen.js:52 $scope.$watch $ionicHistory.backView change detect. newVal: 
pen.js:53 tabs.fact1 
pen.js:58 $timeout after 2 sec $ionicHistory.backView().stateName 
pen.js:59 tabs.fact1 

問題

  1. 如何解決此問題?也許重寫這個委託或以某種方式覆蓋它?

  2. 是否有解決方法?因爲我依靠正確的以前的狀態爲了顯示/隱藏的東西。

JS

angular.module('ionicApp', ['ionic']) 

.config(function($stateProvider, $urlRouterProvider) { 

    $stateProvider 
    .state('tabs', { 
     url: "/tab", 
     abstract: true, 
     templateUrl: "templates/tabs.html", 
     controller: "MainCtrl" 
    }) 
    .state('tabs.home', { 
     url: "/home", 
     views: { 
     'home-tab': { 
      templateUrl: "templates/home.html", 
      controller: 'HomeTabCtrl' 
     } 
     } 
    }) 
    .state('tabs.fact1', { 
     url: "/fact1", 
     views: { 
     'home-tab': { 
      templateUrl: "templates/fact1.html", 
      controller: 'Fact1TabCtrl' 
     } 
     } 
    }) 
    .state('tabs.fact2', { 
     url: "/fact2", 
     views: { 
     'home-tab': { 
      templateUrl: "templates/fact2.html", 
      controller: 'Fact2TabCtrl' 
     } 
     } 
    }) 
    .state('tabs.fact3', { 
     url: "/fact3", 
     views: { 
     'home-tab': { 
      templateUrl: "templates/fact3.html", 
      controller: 'Fact3TabCtrl' 
     } 
     } 
    }) 
    .state('tabs.about', { 
     url: "/about", 
     views: { 
     'about-tab': { 
      templateUrl: "templates/about.html" 
     } 
     } 
    }) 
    .state('tabs.navstack', { 
     url: "/navstack", 
     views: { 
     'about-tab': { 
      templateUrl: "templates/nav-stack.html" 
     } 
     } 
    }); 


    $urlRouterProvider.otherwise("/tab/home"); 

}) 

.controller('MainCtrl', function($scope, $rootScope, $timeout, $ionicHistory) { 
    $scope.$watch(function() { 
    return $ionicHistory.backView() ? $ionicHistory.backView().stateName : null; 
    }, function (newVal, oldVal) { 
    console.log('$scope.$watch $ionicHistory.backView change detect. newVal:'); 
    console.log(newVal); 
    }); 

    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ 
    console.log('stateChangeSuccess'); 

    $timeout(function(){ 
     console.log('$timeout after 2 sec $ionicHistory.backView().stateName'); 
     console.log($ionicHistory.backView().stateName); 
    }, 2000); 
    }); 
}) 

.controller('HomeTabCtrl', function($scope, $rootScope) { 
    // console.log('Home'); 

    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ 
    console.log('State change from: ' + fromState.name + ' to: ' + toState.name); 
    }); 
}) 

.controller('Fact1TabCtrl', function($scope) { 
    // console.log('Fact1'); 
}) 

.controller('Fact2TabCtrl', function($scope) { 
    // console.log('Fact2'); 
}) 

.controller('Fact3TabCtrl', function($scope) { 
    // console.log('Fact3'); 
}); 

HTML

<html ng-app="ionicApp"> 

<head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> 

    <title>Navigation Example</title> 

    <link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet"> 
    <script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script> 
</head> 

<body> 

    <ion-nav-bar class="bar-positive"> 
    <ion-nav-back-button class="button-icon ion-arrow-left-c"> 
    </ion-nav-back-button> 
    </ion-nav-bar> 

    <ion-nav-view></ion-nav-view> 


    <script id="templates/tabs.html" type="text/ng-template"> 
    <ion-tabs class="tabs-icon-top tabs-positive"> 

     <ion-tab title="Home" icon="ion-home" href="#/tab/home"> 
     <ion-nav-view name="home-tab"></ion-nav-view> 
     </ion-tab> 

     <ion-tab title="About" icon="ion-ios-football" href="#/tab/about"> 
     <ion-nav-view name="about-tab"></ion-nav-view> 
     </ion-tab> 

     </ion-tab> 

    </ion-tabs> 
    </script> 

    <script id="templates/home.html" type="text/ng-template"> 
    <ion-view view-title="Home"> 
     <ion-content class="padding"> 
     <p> 
      <a class="button icon ion-home" href="#/tab/home"> Home</a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact1"> 
      Fact1 
      </a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact2"> 
      Fact2 
      </a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact3"> 
      Fact3 
      </a> 
     </p> 
     </ion-content> 
    </ion-view> 
    </script> 

    <script id="templates/fact1.html" type="text/ng-template"> 
    <ion-view view-title="Fact1"> 
     <ion-content class="padding"> 
     <p> 
      <a class="button icon ion-home" href="#/tab/home"> Home</a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact1"> 
      Fact1 
      </a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact2"> 
      Fact2 
      </a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact3"> 
      Fact3 
      </a> 
     </p> 
     </ion-content> 
    </ion-view> 
    </script> 

    <script id="templates/fact2.html" type="text/ng-template"> 
    <ion-view view-title="Fact2"> 
     <ion-content class="padding"> 
     <p> 
      <a class="button icon ion-home" href="#/tab/home"> Home</a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact1"> 
      Fact1 
      </a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact2"> 
      Fact2 
      </a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact3"> 
      Fact3 
      </a> 
     </p> 
     </ion-content> 
    </ion-view> 
    </script> 

    <script id="templates/fact3.html" type="text/ng-template"> 
    <ion-view view-title="Fact3"> 
     <ion-content class="padding"> 
     <p> 
      <a class="button icon ion-home" href="#/tab/home"> Home</a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact1"> 
      Fact1 
      </a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact2"> 
      Fact2 
      </a> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/fact3"> 
      Fact3 
      </a> 
     </p> 
     </ion-content> 
    </ion-view> 
    </script> 

    <script id="templates/about.html" type="text/ng-template"> 
    <ion-view view-title="About"> 
     <ion-content class="padding"> 
     <h3>Create hybrid mobile apps with the web technologies you love.</h3> 
     <p>Free and open source, Ionic offers a library of mobile-optimized HTML, CSS and JS components for building highly interactive apps.</p> 
     <p>Built with Sass and optimized for AngularJS.</p> 
     <p> 
      <a class="button icon icon-right ion-chevron-right" href="#/tab/navstack">Tabs Nav Stack</a> 
     </p> 
     </ion-content> 
    </ion-view> 
    </script> 

    <script id="templates/nav-stack.html" type="text/ng-template"> 
    <ion-view view-title="Tab Nav Stack"> 
     <ion-content class="padding"> 
     <p><img src="http://ionicframework.com/img/diagrams/tabs-nav-stack.png" style="width:100%"></p> 
     </ion-content> 
    </ion-view> 
    </script> 

</body> 

</html> 
+0

有時候會在按下後退按鈕之前發生一些錯誤時發生這種情況 –

+0

含糊不清。什麼是錯誤?據我所知,我在控制檯中沒有錯誤。 –

回答

11

有很多有關的問題包括歷史和導航問題在GitHub上開放。

我猜導航已壞,需要修復。

$ionicHistory跟蹤推送堆棧上每個訪問視圖的視圖。 其實有2列有:

$ionicHistory.viewHistory().views 

$ionicHistory.viewHistory().histories 

我想第一個是,而第二個考慮所有歷史的觀點對於當前堆棧的歷史。
不同的導航可以有不同的歷史:標籤,sidemenu等等,當你從一個歷史切換到另一個時,Ionic應該記住每個狀態。

通過他們documentation閱讀,你可以找到這樣的:

不同於傳統的瀏覽器環境,應用程序和web應用有 平行獨立的歷史,如製表符。如果用戶 在一個選項卡上導航了幾頁深度,然後切換到新選項卡並返回,則返回按鈕不與前一選項卡相關,而是與該選項卡中訪問的前一頁相關。

您可以找到currentHistoryId這裏:$ionicHistory.currentHistoryId()

我已經改變了你的例子一點點進入主控制器的視圖時顯示2個數組:

.controller('MainCtrl', function($scope, $rootScope, $timeout, $ionicHistory) { 
     $scope.$on('$ionicView.enter', function(e) { 
     var history = $ionicHistory.viewHistory(); 
     angular.forEach(history.views, function(view, index){ 
      console.log('views: ' + view.stateName); 
     }); 
     angular.forEach(history.histories[$ionicHistory.currentHistoryId()].stack, function(view, index){ 
      console.log('history stack:' + view.stateName); 
     }); 
    }); 
}) 

正如你所看到的,第一陣列意見跟蹤的各方面的意見你已經去過。
如果您前後訪問,則不會添加元素,前提是您顯示的是之前訪問過的視圖。

每個視圖有兩個屬性:backViewIdforwardViewId。當元素被添加到集合中時,這兩個值似乎是視圖的一部分。導航時它們不會改變。

那麼,什麼情況是,當你按照順序:

Home -> Fact1 -> Fact2 -> Fact3 -> Fact2 

離子發現視圖Fact2集合中,得到它的backViewId(指向Fact1),這就是它將作爲一個視圖中使用回去。

我沒有在代碼中進行一些調試,並試圖強制後視自己,但事情變得混亂。

我想他們已經選擇了這個路徑,因爲當你回到根 - 家 - 後退按鈕應該隱藏。 當您按照以下順序時,事情無法按預期工作:

我注意到的另一件事是,即使元素已經存在,有時視圖也會添加到此集合中。

您可以嘗試的順序:

Home -> Fact1 -> Fact2 - Home (button) 

正如你可以看到現在的後退按鈕(在標題)告訴你的後視圖Fact2而事實上控制檯顯示的一樣:

  • 觀點:tabs.home
  • 觀點:tabs.fact1
  • 觀點:tabs.fact2
  • 觀點:tabs.home
  • 歷史堆棧:這次新tabs.home

一些奇怪的原因:tabs.home

  • 歷史堆棧:tabs.fact1
  • 歷史堆棧:tabs.fact2
  • 歷史堆棧視圖已添加到集合中並且常規模式已更改。

    這裏有一個codepen一些測試。

  • +0

    我正在考慮將此作爲錯誤提交,但只是想問一問,因爲我無法通過搜索$ ionicHistory找到與此相關的任何內容。我認爲解決方法是通過Back按鈕處理狀態導航,與state.go –

    +0

    @HP不同:我已經打開了一個問題。 – LeftyX

    +0

    你能給我發送問題鏈接嗎? –

    0

    我的解決方案/解決方法:

    創建一個額外的狀態遍歷引用相同的URL,templateUrl和控制器。

    例如,如果我有:

    $stateProvider.state('fact2', { url: '/fact2/:factFilter', templateUrl: 'fact2.html', controller: 'Fact2Ctrl' })

    然後我也創建了「fact2」,只有不同的狀態名稱複製

    $stateProvider.state('fact2_duplicate', { url: '/fact2/:factFilter', templateUrl: 'fact2.html', controller: 'Fact2Ctrl' })

    如果我收到有趣的過渡行爲,我可以撥打電話$state.go('fact2_duplicate'),歷史將更符合我的期望。

    希望這可以幫助別人。