Skip to content

Commit 24a488b

Browse files
committed
fix(ionNavButtons): do not append if page is removed very quickly
1 parent d839f4d commit 24a488b

File tree

3 files changed

+88
-33
lines changed

3 files changed

+88
-33
lines changed

Diff for: js/angular/directive/navButtons.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ IonicModule
5858

5959
//Append buttons to navbar
6060
ionic.requestAnimationFrame(function() {
61-
$animate.enter(buttons, navElement);
61+
//If the scope is destroyed before raf runs, be sure not to enter
62+
if (!$scope.$$destroyed) {
63+
$animate.enter(buttons, navElement);
64+
}
6265
});
6366

6467
//When our ion-nav-buttons container is destroyed,

Diff for: test/unit/angular/directive/navBackButton.unit.js

+1-32
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
describe('ionNavBackButton directive', function() {
2-
beforeEach(module('ionic', function($compileProvider) {
3-
$compileProvider.directive('needsScroll', function() {
4-
return {
5-
//Test if the buttons are 'children of ionScroll' when compiled
6-
require: '^$ionicScroll',
7-
link: function(scope, element, attrs, ctrl) {
8-
element.data('scrollCtrl', ctrl);
9-
}
10-
};
11-
});
12-
}));
2+
beforeEach(module('ionic'));
133

144
function setup(attr, content) {
155
var el;
@@ -24,27 +14,6 @@ describe('ionNavBackButton directive', function() {
2414
return el;
2515
}
2616

27-
it('ionNavButtons should compile buttons with same scope & access the same data on compile', inject(function($compile, $rootScope) {
28-
var el = $compile('<div>' +
29-
'<ion-nav-bar></ion-nav-bar>' +
30-
'<ion-view>' +
31-
'<ion-content>' +
32-
'<ion-nav-buttons side="left">' +
33-
'<button needs-scroll>Hello!</button>' +
34-
'</ion-nav-buttons>' +
35-
'</ion-content>' +
36-
'</ion-view>' +
37-
'</div>')($rootScope.$new());
38-
$rootScope.$apply();
39-
expect(el.find('ion-content').children().scope())
40-
.toBe(el.find('.left-buttons button').scope());
41-
42-
//Test if the button was compiled able to access the parents of ion-nav-buttons
43-
var scrollCtrl = el.find('ion-content').controller('$ionicScroll');
44-
expect(scrollCtrl).toBeTruthy();
45-
expect(el.find('button[needs-scroll]').data('scrollCtrl')).toBe(scrollCtrl);
46-
}));
47-
4817
it('should error without a parent ionNavBar', inject(function($compile, $rootScope) {
4918
expect(function() {
5019
$compile('<ion-nav-back-button>')($rootScope);

Diff for: test/unit/angular/directive/navButtons.unit.js

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
ddescribe('ionNavButtons directive', function() {
2+
3+
beforeEach(module('ionic', function($compileProvider) {
4+
$compileProvider.directive('needsScroll', function() {
5+
return {
6+
//Test if the buttons are 'children of ionScroll' when compiled
7+
require: '^$ionicScroll',
8+
link: function(scope, element, attrs, ctrl) {
9+
element.data('scrollCtrl', ctrl);
10+
}
11+
};
12+
});
13+
}));
14+
beforeEach(function() {
15+
ionic.requestAnimationFrame = function(cb) { cb(); };
16+
});
17+
18+
function setup(side, tpl) {
19+
var el;
20+
inject(function($compile, $rootScope) {
21+
el = $compile('<div>' +
22+
'<ion-nav-bar></ion-nav-bar>' +
23+
'<ion-view>' +
24+
'<ion-content>' +
25+
'<ion-nav-buttons side="'+(side)+'">' +
26+
(tpl || '') +
27+
'</ion-nav-buttons>' +
28+
'</ion-content>' +
29+
'</ion-view>' +
30+
'</div>')($rootScope.$new());
31+
$rootScope.$apply();
32+
});
33+
return el;
34+
}
35+
36+
it('should add buttons to left side by default', function() {
37+
var el = setup(null, '<button id="my-btn">');
38+
expect(el[0].querySelector('.left-buttons #my-btn')).toBeTruthy();
39+
expect(el[0].querySelector('.right-buttons #my-btn')).toBeFalsy();
40+
});
41+
42+
it('should add buttons to left side', function() {
43+
var el = setup('left', '<button id="my-btn">');
44+
expect(el[0].querySelector('.left-buttons #my-btn')).toBeTruthy();
45+
expect(el[0].querySelector('.right-buttons #my-btn')).toBeFalsy();
46+
});
47+
48+
it('should add buttons to right side', function() {
49+
var el = setup('right', '<button id="my-btn">');
50+
expect(el[0].querySelector('.left-buttons #my-btn')).toBeFalsy();
51+
expect(el[0].querySelector('.right-buttons #my-btn')).toBeTruthy();
52+
});
53+
54+
it('should remove buttons on content destroy', function() {
55+
var el = setup('', '<button id="my-btn">');
56+
expect(el[0].querySelector('.left-buttons #my-btn')).toBeTruthy();
57+
el.find('ion-nav-buttons').scope().$destroy();
58+
el.scope().$apply();
59+
expect(el[0].querySelector('.left-buttons #my-btn')).toBeFalsy();
60+
});
61+
62+
it('should compile buttons with same scope & access the same data on compile', function() {
63+
var el = setup('left', '<button needs-scroll>Hello!</button>');
64+
expect(jqLite(el[0].querySelector('ion-content')).children().scope().$id)
65+
.toBe(jqLite(el[0].querySelector('.left-buttons button')).scope().$id);
66+
67+
//Test if the button was compiled able to access the parents of ion-nav-buttons
68+
var scrollCtrl = el.find('ion-content').controller('$ionicScroll');
69+
expect(scrollCtrl).toBeTruthy();
70+
expect(el.find('button[needs-scroll]').data('scrollCtrl')).toBe(scrollCtrl);
71+
});
72+
73+
it('should not enter if button is destroyed before raf', function() {
74+
var rafCb;
75+
ionic.requestAnimationFrame = function(cb) { rafCb = cb; };
76+
var el = setup('left', '<button id="my-btn">');
77+
el.find('ion-content').scope().$destroy();
78+
el.scope().$apply();
79+
rafCb();
80+
expect(el[0].querySelector('.left-buttons #my-btn')).toBeFalsy();
81+
});
82+
83+
});

0 commit comments

Comments
 (0)