我做了一个小实验:http : //codepen.io/hawkphil/pen/NqMomm?editors=101
这是我的状态流(单击按钮): Home -> Fact1 -> Fact2 -> Fact3 -> Fact2
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状态。我还显示了(line )中的值,以防万一它很慢。但这仍然是不正确的。 *$timeout``pen.js:59
console.log
$ionicHistory.backView
pen.js:64
app.fact2
app.fact1
pen.js:53
app.fact3
$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
题
如何纠正这种行为?也许重写此委托或以某种方式覆盖它?
有解决方法吗?因为我依靠正确的 先前状态 来显示/隐藏某些东西。
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>
在github上公开的问题中,有很多关于历史和导航的问题。
我猜导航坏了,需要修复。
$ionicHistory跟踪视图,将每个访问的视图推入堆栈。实际上那里有2个数组:
$ionicHistory
$ionicHistory.viewHistory().views
和
$ionicHistory.viewHistory().histories
我猜第一个是当前堆栈视图的历史记录,第二个是所有历史记录。 不同的导航可能具有不同的历史记录:选项卡,菜单等,当您从一种历史记录切换到另一种历史记录时,Ionic应该记住每种状态。
阅读他们的文档,您会发现:
与传统的浏览器环境不同,应用程序和Web应用程序具有并行的独立历史记录,例如带有选项卡的历史记录。如果用户在一个选项卡上深入浏览了几页,然后切换到新选项卡,然后返回,则后退按钮不与上一个选项卡相关,而是与该选项卡中访问的先前页面有关。
您可以在此处找到 currentHistoryId :$ionicHistory.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); }); }); })
如您所见,第一个数组 视图 跟踪您访问过的所有视图。 如果您来回走,则在显示以前访问过的视图时不添加元素。
每个视图都有两个属性: backViewId 和 forwardViewId 。将元素添加到集合时,这两个值似乎是视图的一部分。它们在您导航时不会改变。
因此,当您按照以下顺序进行时,会发生什么:
Ionic Fact2在集合中找到视图,得到它backViewId(指向Fact1),这就是将其用作视图的基础。
Fact2
backViewId
Fact1
我没有在代码中进行一些调试,而是试图自己强制执行后视图,但是事情变得一团糟。
我想他们已经选择了此路径,当您回到根目录-主页-后退按钮应该被隐藏。遵循以下顺序时,事情将无法按预期进行:
我注意到的另一件事是,即使元素已经存在,有时也会将视图添加到此集合中。
您可以尝试以下顺序:
Home -> Fact1 -> Fact2 - Home (button)
如您现在所见,后退按钮(位于标题中)告诉您后视图为Fact2,实际上控制台显示的内容相同:
出于某些奇怪的原因,这次将新视图添加到集合中,并且常规模式已更改。
这里有一些测试的codepen。