mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(ionView): observe for attr changes
This commit is contained in:
59
js/angular/controller/viewController.js
vendored
59
js/angular/controller/viewController.js
vendored
@@ -12,6 +12,7 @@ function($scope, $element, $attrs, $compile, $ionicHistory, $ionicViewSwitcher)
|
||||
var navViewCtrl;
|
||||
var navBarDelegateHandle;
|
||||
var hasViewHeaderBar;
|
||||
var deregisters = [];
|
||||
|
||||
var deregIonNavBarInit = $scope.$on('ionNavBar.init', function(ev, delegateHandle){
|
||||
// this view has its own ion-nav-bar, remember the navBarDelegateHandle for this view
|
||||
@@ -38,13 +39,8 @@ function($scope, $element, $attrs, $compile, $ionicHistory, $ionicViewSwitcher)
|
||||
|
||||
// add listeners for when this view changes
|
||||
$scope.$on('$ionicView.beforeEnter', self.beforeEnter);
|
||||
$scope.$on('$ionicView.afterEnter', self.afterEnter);
|
||||
|
||||
// watch to see if the hideNavBar attribute changes
|
||||
var hideNavAttr = isDefined($attrs.hideNavBar) ? $attrs.hideNavBar : 'false';
|
||||
$scope.$watch(hideNavAttr, function(value) {
|
||||
navViewCtrl.showBar(!value);
|
||||
});
|
||||
$scope.$on('$ionicView.afterEnter', afterEnter);
|
||||
$scope.$on('$ionicView.beforeLeave', deregisterObservers);
|
||||
};
|
||||
|
||||
self.beforeEnter = function(ev, transData) {
|
||||
@@ -68,16 +64,55 @@ function($scope, $element, $attrs, $compile, $ionicHistory, $ionicViewSwitcher)
|
||||
transition: transData.transition,
|
||||
transitionId: transData.transitionId,
|
||||
shouldAnimate: transData.shouldAnimate,
|
||||
showBack: transData.showBack && !$attrs.hideBackButton,
|
||||
showBack: transData.showBack && !attrTrue('hideBackButton'),
|
||||
buttons: buttons,
|
||||
navBarDelegate: navBarDelegateHandle || null,
|
||||
showNavBar: !($attrs.hideNavBar === "true" || $attrs.hideNavBar === ""),
|
||||
showNavBar: !attrTrue('hideNavBar'),
|
||||
hasHeaderBar: !!hasViewHeaderBar
|
||||
});
|
||||
|
||||
// make sure any existing observers are cleaned up
|
||||
deregisterObservers();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function afterEnter() {
|
||||
// only listen for title updates after it has entered
|
||||
// but also deregister the observe before it leaves
|
||||
var viewTitleAttr = isDefined($attrs.viewTitle) && 'viewTitle' || isDefined($attrs.title) && 'title';
|
||||
if (viewTitleAttr) {
|
||||
deregisters.push($attrs.$observe(viewTitleAttr, function(val) {
|
||||
navViewCtrl.title(val);
|
||||
$ionicHistory.currentTitle(val);
|
||||
}));
|
||||
}
|
||||
|
||||
if (isDefined($attrs.hideBackButton)) {
|
||||
deregisters.push($attrs.$observe('hideBackButton', function() {
|
||||
navViewCtrl.showBackButton(!attrTrue('hideBackButton'));
|
||||
}));
|
||||
}
|
||||
|
||||
if (isDefined($attrs.hideNavBar)) {
|
||||
deregisters.push($attrs.$observe('hideNavBar', function() {
|
||||
navViewCtrl.showBar(!attrTrue('hideNavBar'));
|
||||
}));
|
||||
}
|
||||
|
||||
$ionicViewSwitcher.setActiveView($element.parent());
|
||||
}
|
||||
|
||||
|
||||
function deregisterObservers() {
|
||||
// remove all existing $attrs.$observe's
|
||||
for (var x = 0; x < deregisters.length; x++) {
|
||||
deregisters[x]();
|
||||
}
|
||||
deregisters = [];
|
||||
}
|
||||
|
||||
|
||||
function generateButton(html) {
|
||||
if (html) {
|
||||
// every time a view enters we need to recreate its view buttons if they exist
|
||||
@@ -86,9 +121,9 @@ function($scope, $element, $attrs, $compile, $ionicHistory, $ionicViewSwitcher)
|
||||
}
|
||||
|
||||
|
||||
self.afterEnter = function(ev, transitionData) {
|
||||
$ionicViewSwitcher.setActiveView($element.parent());
|
||||
};
|
||||
function attrTrue(key) {
|
||||
return $attrs[key] == 'true' || $attrs[key] === '';
|
||||
}
|
||||
|
||||
|
||||
self.navElement = function(type, html) {
|
||||
|
||||
@@ -11,7 +11,9 @@ describe('ionView directive', function() {
|
||||
el = angular.element('<ion-view '+(attrs||'')+'>');
|
||||
el.data('$ionNavViewController', {
|
||||
beforeEnter: function(d) { beforeEnterData = d; },
|
||||
title: jasmine.createSpy('title'),
|
||||
showBar: jasmine.createSpy('showBar'),
|
||||
showBackButton: jasmine.createSpy('showBackButton')
|
||||
});
|
||||
content && el.html(content);
|
||||
|
||||
@@ -116,4 +118,73 @@ describe('ionView directive', function() {
|
||||
expect( beforeEnterData.hasHeaderBar ).toBe(true);
|
||||
}));
|
||||
|
||||
it('should only observe title attr after afterEnter and before beforeLeave', inject(function($rootScope) {
|
||||
var el = setup('view-title="{{ myTitle }}"', {myTitle: 'My Title'});
|
||||
$rootScope.$broadcast('$ionicView.beforeEnter', {});
|
||||
var spy = el.data('$ionNavViewController').title;
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
|
||||
$rootScope.$broadcast('$ionicView.afterEnter', {});
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
|
||||
el.scope().myTitle = 'My New Title';
|
||||
$rootScope.$digest();
|
||||
expect(spy).toHaveBeenCalledWith('My New Title');
|
||||
spy.reset();
|
||||
|
||||
$rootScope.$broadcast('$ionicView.beforeLeave', {});
|
||||
el.scope().myTitle = 'My Other New Title';
|
||||
$rootScope.$digest();
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
}));
|
||||
|
||||
it('should only observe hideNavBar attr after afterEnter and before beforeLeave', inject(function($rootScope) {
|
||||
var el = setup('hide-nav-bar="{{ hide }}"', {hide: false});
|
||||
$rootScope.$broadcast('$ionicView.beforeEnter', {});
|
||||
var spy = el.data('$ionNavViewController').showBar;
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
|
||||
$rootScope.$broadcast('$ionicView.afterEnter', {});
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
|
||||
el.scope().hide = true;
|
||||
$rootScope.$digest();
|
||||
expect(spy).toHaveBeenCalledWith(false);
|
||||
spy.reset();
|
||||
|
||||
$rootScope.$broadcast('$ionicView.beforeLeave', {});
|
||||
el.scope().hide = false;
|
||||
$rootScope.$digest();
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
}));
|
||||
|
||||
it('should only observe hideBackButton attr after afterEnter and before beforeLeave', inject(function($rootScope) {
|
||||
var el = setup('hide-back-button="{{ hide }}"', {hide: false});
|
||||
$rootScope.$broadcast('$ionicView.beforeEnter', {});
|
||||
var spy = el.data('$ionNavViewController').showBackButton;
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
|
||||
$rootScope.$broadcast('$ionicView.afterEnter', {});
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
|
||||
el.scope().hide = true;
|
||||
$rootScope.$digest();
|
||||
expect(spy).toHaveBeenCalledWith(false);
|
||||
spy.reset();
|
||||
|
||||
$rootScope.$broadcast('$ionicView.beforeLeave', {});
|
||||
el.scope().hide = false;
|
||||
$rootScope.$digest();
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
spy.reset();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user