Skip to content

Commit e31498c

Browse files
committed
fix(navigation): revert previous navigation fix (efb9bd) and added a different fix for the infite lo
revert previous navigation fix (efb9bd) and added a different fix for the infite loop issue. Wrote additional tests to verify the fix
1 parent d86bf87 commit e31498c

File tree

2 files changed

+221
-22
lines changed

2 files changed

+221
-22
lines changed

Diff for: js/angular/service/history.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ function($rootScope, $state, $location, $window, $timeout, $ionicViewSwitcher, $
277277
// it's back view would be better represented using the current view as its back view
278278
tmp = getViewById(switchToView.backViewId);
279279
if (tmp && switchToView.historyId !== tmp.historyId) {
280+
// the new view is being removed from it's old position in the history and being placed at the top,
281+
// so we need to update any views that reference it as a backview, otherwise there will be infinitely loops
282+
var viewIds = Object.keys(viewHistory.views);
283+
viewIds.forEach(function(viewId) {
284+
var view = viewHistory.views[viewId];
285+
if ( view.backViewId === switchToView.viewId ) {
286+
view.backViewId = null;
287+
}
288+
});
289+
280290
hist.stack[hist.cursor].backViewId = currentView.viewId;
281291
}
282292

@@ -355,7 +365,7 @@ function($rootScope, $state, $location, $window, $timeout, $ionicViewSwitcher, $
355365
viewId: viewId,
356366
index: hist.stack.length,
357367
historyId: hist.historyId,
358-
backViewId: (currentView && currentView.viewId && (currentView.historyId === hist.historyId || currentView.historyId === hist.parentHistoryId) ? currentView.viewId : null),
368+
backViewId: (currentView && currentView.viewId ? currentView.viewId : null),
359369
forwardViewId: null,
360370
stateId: currentStateId,
361371
stateName: this.currentStateName(),

Diff for: test/unit/angular/service/history.unit.js

+210-21
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ describe('Ionic History', function() {
55
stateProvider = $stateProvider;
66

77
$stateProvider
8-
.state('home', { url: "/" })
9-
.state('home.item', { url: "front/:id" })
8+
.state('home', { url: '/' })
9+
.state('home.item', { url: 'front/:id' })
1010

11-
.state('about', { url: "/about" })
12-
.state('about.person', { url: "/person" })
13-
.state('about.person.item', { url: "/id" })
11+
.state('about', { url: '/about' })
12+
.state('about.person', { url: '/person' })
13+
.state('about.person.item', { url: '/id' })
1414

1515
.state('about.sidebar', {})
1616
.state('about.sidebar.item', {})
1717

18-
.state('contact', { url: "/contact" })
18+
.state('contact', { url: '/contact' })
1919

20-
.state('info', { url: "/info" })
20+
.state('info', { url: '/info' })
2121

2222
.state('tabs', { abstract: true })
2323
.state('tabs.tab1view1', {})
@@ -231,9 +231,10 @@ describe('Ionic History', function() {
231231
currentView = ionicHistory.currentView();
232232
backView = ionicHistory.backView();
233233
forwardView = ionicHistory.forwardView();
234-
expect(currentView.backViewId).toEqual(null);
234+
expect(currentView.backViewId).toEqual(tab1view1Reg.viewId);
235235
expect(currentView.forwardViewId).toEqual(null);
236-
expect(backView).toEqual(null);
236+
expect(backView.viewId).toEqual(tab1view1Reg.viewId);
237+
expect(backView.forwardViewId).toEqual(currentView.viewId);
237238

238239
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(2);
239240
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(3);
@@ -291,7 +292,7 @@ describe('Ionic History', function() {
291292
expect(homeReg2.action).toEqual('moveBack');
292293
expect(homeReg2.direction).toEqual('back');
293294

294-
// this should overwrite that we went to the "about" view
295+
// this should overwrite that we went to the 'about' view
295296
contactScope = {};
296297
$state.go('contact');
297298
rootScope.$apply();
@@ -644,7 +645,7 @@ describe('Ionic History', function() {
644645

645646
// go back to tab1, and it should load the first view of tab1
646647
expect(tab1Scope.$historyId).toEqual(orgTab1HistoryId);
647-
rootScope.$broadcast("$ionicHistory.change", { historyId: tab1Scope.$historyId, enableUrlChange: false });
648+
rootScope.$broadcast('$ionicHistory.change', { historyId: tab1Scope.$historyId, enableUrlChange: false });
648649
rootScope.$apply();
649650
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view1');
650651
registerData = ionicHistory.register(tab1view1Scope, false);
@@ -688,11 +689,11 @@ describe('Ionic History', function() {
688689
expect(registerData.action).toEqual('moveBack');
689690
expect(registerData.direction).toEqual('swap');
690691
currentView = ionicHistory.currentView();
691-
expect(currentView.backViewId).toEqual(null);
692+
expect(currentView.backViewId).toEqual(tab1view2ViewId);
692693
expect(currentView.forwardViewId).toEqual(null);
693694

694695
// should be remembered at the tab 1 view 2
695-
rootScope.$broadcast("$ionicHistory.change", { historyId: tab1Scope.$historyId });
696+
rootScope.$broadcast('$ionicHistory.change', { historyId: tab1Scope.$historyId });
696697
rootScope.$apply();
697698
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view2');
698699
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(1);
@@ -1293,37 +1294,37 @@ describe('Ionic History', function() {
12931294
it('should change history on event changeHistory', inject(function($location, $state) {
12941295
$location.url('/original');
12951296

1296-
rootScope.$broadcast("$ionicHistory.change");
1297+
rootScope.$broadcast('$ionicHistory.change');
12971298
expect($location.url()).toEqual('/original');
12981299

1299-
rootScope.$broadcast("$ionicHistory.change", { uiSref: 'about' });
1300+
rootScope.$broadcast('$ionicHistory.change', { uiSref: 'about' });
13001301
expect($location.url()).toEqual('/about');
13011302

1302-
rootScope.$broadcast("$ionicHistory.change", { url: '/url' });
1303+
rootScope.$broadcast('$ionicHistory.change', { url: '/url' });
13031304
expect($location.url()).toEqual('/url');
13041305

13051306
ionicHistory.viewHistory().histories.h123 = { stack: [], cursor: -1 };
1306-
rootScope.$broadcast("$ionicHistory.change", { historyId: 'h123' });
1307+
rootScope.$broadcast('$ionicHistory.change', { historyId: 'h123' });
13071308
expect($location.url()).toEqual('/url');
13081309

13091310
var newView = ionicHistory.createView({ stateName: 'about' });
13101311
ionicHistory.viewHistory().histories.h123.stack.push(newView);
13111312
ionicHistory.viewHistory().histories.h123.cursor++;
1312-
rootScope.$broadcast("$ionicHistory.change", { historyId: 'h123' });
1313+
rootScope.$broadcast('$ionicHistory.change', { historyId: 'h123' });
13131314
rootScope.$apply();
13141315
expect($state.current.name).toEqual('about');
13151316
}));
13161317

13171318
it('should update document title', inject(function($document) {
13181319
$document[0].title = 'Original Title';
13191320

1320-
rootScope.$broadcast("$ionicView.afterEnter");
1321+
rootScope.$broadcast('$ionicView.afterEnter');
13211322
expect($document[0].title).toEqual('Original Title');
13221323

1323-
rootScope.$broadcast("$ionicView.afterEnter", {});
1324+
rootScope.$broadcast('$ionicView.afterEnter', {});
13241325
expect($document[0].title).toEqual('Original Title');
13251326

1326-
rootScope.$broadcast("$ionicView.afterEnter", { title: 'New Title' });
1327+
rootScope.$broadcast('$ionicView.afterEnter', { title: 'New Title' });
13271328
expect($document[0].title).toEqual('New Title');
13281329
}));
13291330

@@ -1358,4 +1359,192 @@ describe('Ionic History', function() {
13581359

13591360
}));
13601361

1362+
it('should wipe out any back view references to a view when revisiting that view', inject(function($state, $ionicHistory) {
1363+
1364+
var tab1Container = {};
1365+
var tab2Container = {};
1366+
var tab3Container = {};
1367+
ionicHistory.registerHistory(tab1Container);
1368+
ionicHistory.registerHistory(tab2Container);
1369+
ionicHistory.registerHistory(tab3Container);
1370+
1371+
// register tab1, view1
1372+
$state.go('tabs.tab1view1');
1373+
rootScope.$apply();
1374+
var tab1view1Reg = ionicHistory.register(tab1Container, false);
1375+
expect(ionicHistory.viewHistory().histories[tab1Container.$historyId].cursor).toEqual(0);
1376+
1377+
// register tab3, view1
1378+
$state.go('tabs.tab3view1');
1379+
rootScope.$apply();
1380+
var tab3view1Reg = ionicHistory.register(tab3Container, false);
1381+
1382+
// register tab2, view1
1383+
$state.go('tabs.tab2view1');
1384+
rootScope.$apply();
1385+
var tab2view1Reg = ionicHistory.register(tab2Container, false);
1386+
1387+
// go to tab2, view 2
1388+
// register tab1, view2
1389+
$state.go('tabs.tab2view2');
1390+
rootScope.$apply();
1391+
var tab2view2Reg = ionicHistory.register(tab2Container, false);
1392+
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].cursor).toEqual(1);
1393+
currentView = ionicHistory.currentView();
1394+
expect(currentView.backViewId).toEqual(tab2view1Reg.viewId);
1395+
1396+
// register tab3, view1
1397+
$state.go('tabs.tab3view1');
1398+
rootScope.$apply();
1399+
tab3view1Reg = ionicHistory.register(tab3Container, false);
1400+
1401+
currentView = ionicHistory.currentView();
1402+
expect(currentView.backViewId).toEqual(tab2view2Reg.viewId);
1403+
1404+
backView = ionicHistory.getViewById(currentView.backViewId);
1405+
expect(backView.backViewId).toEqual(tab2view1Reg.viewId);
1406+
1407+
var backBackView = ionicHistory.getViewById(backView.backViewId);
1408+
expect(backBackView.backViewId).toEqual(null);
1409+
1410+
}));
1411+
1412+
it('should be able to go forward from non-tabbed view, to tabbed-view, to different non-tabbed view, and then all the way back', inject(function($state, $ionicHistory) {
1413+
1414+
$state.go('home');
1415+
rootScope.$apply();
1416+
var view1Scope = {};
1417+
var rsp = ionicHistory.register(view1Scope, false);
1418+
1419+
var tab1Container = {};
1420+
ionicHistory.registerHistory(tab1Container);
1421+
1422+
// register tab1, view1
1423+
$state.go('tabs.tab1view1');
1424+
rootScope.$apply();
1425+
var tab1view1Reg = ionicHistory.register(tab1Container, false);
1426+
expect(ionicHistory.viewHistory().histories[tab1Container.$historyId].cursor).toEqual(0);
1427+
1428+
$state.go('about');
1429+
rootScope.$apply();
1430+
rsp = ionicHistory.register({}, false);
1431+
1432+
var currentView = ionicHistory.currentView();
1433+
var backView = ionicHistory.getViewById(currentView.backViewId);
1434+
1435+
expect(currentView.stateName).toEqual('about');
1436+
expect(backView.stateName).toEqual('tabs.tab1view1');
1437+
1438+
var originalView = ionicHistory.getViewById(backView.backViewId);
1439+
expect(originalView.stateName).toEqual('home');
1440+
1441+
}));
1442+
1443+
it('should be able to go forward from non-tabbed view, to multiple tabbed-views, to different non-tabbed view, and then all the way back', inject(function($state, $ionicHistory) {
1444+
1445+
$state.go('home');
1446+
rootScope.$apply();
1447+
var view1Scope = {};
1448+
var rsp = ionicHistory.register(view1Scope, false);
1449+
1450+
var tab1Container = {};
1451+
var tab2Container = {};
1452+
var tab3Container = {};
1453+
ionicHistory.registerHistory(tab1Container);
1454+
ionicHistory.registerHistory(tab2Container);
1455+
ionicHistory.registerHistory(tab3Container);
1456+
1457+
// register tab1, view1
1458+
$state.go('tabs.tab1view1');
1459+
rootScope.$apply();
1460+
var tab1view1Reg = ionicHistory.register(tab1Container, false);
1461+
expect(ionicHistory.viewHistory().histories[tab1Container.$historyId].cursor).toEqual(0);
1462+
1463+
$state.go('tabs.tab2view1');
1464+
rootScope.$apply();
1465+
var tab2view1Reg = ionicHistory.register(tab2Container, false);
1466+
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].cursor).toEqual(0);
1467+
1468+
$state.go('tabs.tab2view2');
1469+
rootScope.$apply();
1470+
var tab2view2Reg = ionicHistory.register(tab2Container, false);
1471+
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].cursor).toEqual(1);
1472+
1473+
$state.go('tabs.tab3view1');
1474+
rootScope.$apply();
1475+
var tab3view1Reg = ionicHistory.register(tab3Container, false);
1476+
expect(ionicHistory.viewHistory().histories[tab3Container.$historyId].cursor).toEqual(0);
1477+
1478+
$state.go('tabs.tab3view2');
1479+
rootScope.$apply();
1480+
var tab3view2Reg = ionicHistory.register(tab3Container, false);
1481+
expect(ionicHistory.viewHistory().histories[tab3Container.$historyId].cursor).toEqual(1);
1482+
1483+
$state.go('about');
1484+
rootScope.$apply();
1485+
rsp = ionicHistory.register({}, false);
1486+
1487+
var currentView = ionicHistory.currentView();
1488+
var backView = ionicHistory.getViewById(currentView.backViewId);
1489+
1490+
expect(currentView.stateName).toEqual('about');
1491+
expect(backView.stateName).toEqual('tabs.tab3view2');
1492+
1493+
// update the backview
1494+
backView = ionicHistory.getViewById(backView.backViewId);
1495+
expect(backView.stateName).toEqual('tabs.tab3view1');
1496+
1497+
backView = ionicHistory.getViewById(backView.backViewId);
1498+
expect(backView.stateName).toEqual('tabs.tab2view2');
1499+
1500+
backView = ionicHistory.getViewById(backView.backViewId);
1501+
expect(backView.stateName).toEqual('tabs.tab2view1');
1502+
1503+
backView = ionicHistory.getViewById(backView.backViewId);
1504+
expect(backView.stateName).toEqual('tabs.tab1view1');
1505+
1506+
backView = ionicHistory.getViewById(backView.backViewId);
1507+
expect(backView.stateName).toEqual('home');
1508+
1509+
}));
1510+
1511+
it('should navigate forward then be able to get back via backViews', inject(function($state, $ionicHistory) {
1512+
1513+
$state.go('home');
1514+
rootScope.$apply();
1515+
var homeScope = {};
1516+
var home = ionicHistory.register(homeScope, false);
1517+
1518+
$state.go('about');
1519+
rootScope.$apply();
1520+
var aboutScope = {};
1521+
var about = ionicHistory.register(aboutScope, false);
1522+
1523+
$state.go('contact');
1524+
rootScope.$apply();
1525+
var contactScope = {};
1526+
var contact = ionicHistory.register(contactScope, false);
1527+
1528+
$state.go('home');
1529+
rootScope.$apply();
1530+
var homeScope = {};
1531+
var home = ionicHistory.register(homeScope, false);
1532+
1533+
var currentView = ionicHistory.currentView();
1534+
expect(currentView.stateName).toEqual('home');
1535+
1536+
var backView = ionicHistory.getViewById(currentView.backViewId);
1537+
expect(backView.stateName).toEqual('contact');
1538+
1539+
// update the backview
1540+
backView = ionicHistory.getViewById(backView.backViewId);
1541+
expect(backView.stateName).toEqual('about');
1542+
1543+
// update the backview
1544+
backView = ionicHistory.getViewById(backView.backViewId);
1545+
expect(backView.stateName).toEqual('home');
1546+
expect(backView.backViewId).toEqual(null);
1547+
1548+
}));
1549+
13611550
});

0 commit comments

Comments
 (0)