mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
refactor(ionNavButtons): compile in the correct context
This commit is contained in:
@@ -1,67 +0,0 @@
|
||||
describe('ionNavButtons directive', function() {
|
||||
|
||||
beforeEach(module('ionic.ui.navBar'));
|
||||
function setup(attrs, contents) {
|
||||
var el;
|
||||
inject(function($compile, $rootScope) {
|
||||
el = angular.element('<ion-nav-buttons ' + (attrs||'') + '>'+(contents||'')+'</ion-nav-buttons>');
|
||||
el.data('$ionNavBarController', {
|
||||
leftButtonsElement: angular.element('<div>'),
|
||||
rightButtonsElement: angular.element('<div>')
|
||||
});
|
||||
el = $compile(el)($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
});
|
||||
return el;
|
||||
}
|
||||
|
||||
it('should error without parent navBar', inject(function($compile, $rootScope) {
|
||||
expect(function() {
|
||||
$compile('<ion-nav-buttons>')($rootScope.$new());
|
||||
}).toThrow();
|
||||
}));
|
||||
|
||||
it('should make the container element end up display:none', function() {
|
||||
var el = setup();
|
||||
expect(el.css('display')).toBe('none');
|
||||
});
|
||||
|
||||
it('should transclude contents into left', function() {
|
||||
var el = setup('side="left" ng-init="items=[1,2]"', '<button ng-repeat="i in items">{{i}}</button>');
|
||||
var leftButtons = el.controller('ionNavBar').leftButtonsElement.children();
|
||||
expect(leftButtons.text().trim()).toEqual('12');
|
||||
el.scope().$apply('items=[1,3,5]');
|
||||
expect(leftButtons.text().trim()).toEqual('135');
|
||||
});
|
||||
|
||||
it('should transclude contents into right', function() {
|
||||
var el = setup('side="right" ng-init="items=[1,2]"', '<button ng-repeat="i in items">{{i}}</button>');
|
||||
var rightButtons = el.controller('ionNavBar').rightButtonsElement.children();
|
||||
expect(rightButtons.text().trim()).toEqual('12');
|
||||
el.scope().$apply('items=[1,3,5]');
|
||||
expect(rightButtons.text().trim()).toEqual('135');
|
||||
});
|
||||
|
||||
it('left should destroy contents on scope destroy', inject(function($animate) {
|
||||
spyOn($animate, 'leave');
|
||||
|
||||
var el = setup('side="left" ng-init="items=[1,2]"', '<button ng-repeat="i in items">{{i}}</button>');
|
||||
var leftButtons = el.controller('ionNavBar').leftButtonsElement.children();
|
||||
expect(leftButtons.text().trim()).toEqual('12');
|
||||
el.scope().$destroy();
|
||||
expect($animate.leave).toHaveBeenCalled();
|
||||
expect($animate.leave.mostRecentCall.args[0][0]).toBe(leftButtons[0]);
|
||||
}));
|
||||
|
||||
it('right should destroy contents on scope destroy', inject(function($animate) {
|
||||
spyOn($animate, 'leave');
|
||||
|
||||
var el = setup('side="right" ng-init="items=[1,2]"', '<button ng-repeat="i in items">{{i}}</button>');
|
||||
var rightButtons = el.controller('ionNavBar').rightButtonsElement.children();
|
||||
expect(rightButtons.text().trim()).toEqual('12');
|
||||
el.scope().$destroy();
|
||||
expect($animate.leave).toHaveBeenCalled();
|
||||
expect($animate.leave.mostRecentCall.args[0][0]).toBe(rightButtons[0]);
|
||||
}));
|
||||
|
||||
});
|
||||
10
js/ext/angular/src/directive/ionicNavBar.js
vendored
10
js/ext/angular/src/directive/ionicNavBar.js
vendored
@@ -381,6 +381,7 @@ function($ionicViewService, $rootScope, $animate, $compile, $parse) {
|
||||
require: '^ionNavBar',
|
||||
restrict: 'E',
|
||||
compile: function($element, $attrs) {
|
||||
var content = $element.contents().remove();
|
||||
return function($scope, $element, $attrs, navBarCtrl) {
|
||||
var navElement = $attrs.side === 'right' ?
|
||||
navBarCtrl.rightButtonsElement :
|
||||
@@ -390,7 +391,14 @@ function($ionicViewService, $rootScope, $animate, $compile, $parse) {
|
||||
//so we can remove them all when this element dies -
|
||||
//even if the buttons have changed through an ng-repeat or the like,
|
||||
//we just remove their div parent and they are gone.
|
||||
var buttons = angular.element('<div>').append($element.contents().remove());
|
||||
var buttons = angular.element('<div>').append(content);
|
||||
|
||||
//Compile buttons inside content so they have access to everything
|
||||
//something inside content does (eg parent ionicScroll)
|
||||
$element.append(buttons);
|
||||
$compile(buttons)($scope);
|
||||
|
||||
//Append buttons to navbar
|
||||
$animate.enter(buttons, navElement);
|
||||
|
||||
//When our ion-nav-buttons container is destroyed,
|
||||
|
||||
24
js/ext/angular/src/directive/ionicViewState.js
vendored
24
js/ext/angular/src/directive/ionicViewState.js
vendored
@@ -40,11 +40,6 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu
|
||||
restrict: 'EA',
|
||||
priority: 1000,
|
||||
require: '^?ionNavBar',
|
||||
scope: {
|
||||
title: '@',
|
||||
hideBackButton: '&',
|
||||
hideNavBar: '&',
|
||||
},
|
||||
compile: function(tElement, tAttrs, transclude) {
|
||||
tElement.addClass('pane');
|
||||
tElement[0].removeAttribute('title');
|
||||
@@ -53,18 +48,21 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu
|
||||
if (!navBarCtrl) {
|
||||
return;
|
||||
}
|
||||
navBarCtrl.changeTitle($scope.title, $scope.$parent.$navDirection);
|
||||
navBarCtrl.changeTitle($attr.title, $scope.$navDirection);
|
||||
|
||||
// Should we hide a back button when this tab is shown
|
||||
navBarCtrl.showBackButton(!$scope.hideBackButton());
|
||||
$scope.$watch($attr.hideBackButton, function(value) {
|
||||
// Should we hide a back button when this tab is shown
|
||||
navBarCtrl.showBackButton(!value);
|
||||
});
|
||||
|
||||
// Should the nav bar be hidden for this view or not?
|
||||
navBarCtrl.showBar(!$scope.hideNavBar());
|
||||
$scope.$watch($attr.hideNavBar, function(value) {
|
||||
// Should the nav bar be hidden for this view or not?
|
||||
navBarCtrl.showBar(!value);
|
||||
});
|
||||
|
||||
// watch for changes in the title
|
||||
$scope.$watch('title', function(val, oldVal) {
|
||||
//Don't send in initial value, changeTitle does that
|
||||
if (val !== oldVal) {
|
||||
$attr.$observe('title', function(val, oldVal) {
|
||||
if (val) {
|
||||
navBarCtrl.setTitle(val);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
describe('ionNavBackButton directive', function() {
|
||||
beforeEach(module('ionic'));
|
||||
beforeEach(module('ionic', function($compileProvider) {
|
||||
$compileProvider.directive('needsScroll', function() {
|
||||
return {
|
||||
//Test if the buttons are 'children of ionScroll' when compiled
|
||||
require: '^$ionicScroll',
|
||||
link: function(scope, element, attrs, ctrl) {
|
||||
element.data('scrollCtrl', ctrl);
|
||||
}
|
||||
};
|
||||
});
|
||||
}));
|
||||
|
||||
function setup(attr, content) {
|
||||
var el;
|
||||
@@ -14,6 +24,27 @@ describe('ionNavBackButton directive', function() {
|
||||
return el;
|
||||
}
|
||||
|
||||
it('should compile buttons with same scope & access the same data on compile', inject(function($compile, $rootScope) {
|
||||
var el = $compile('<div>' +
|
||||
'<ion-nav-bar></ion-nav-bar>' +
|
||||
'<ion-view>' +
|
||||
'<ion-content>' +
|
||||
'<ion-nav-buttons side="left">' +
|
||||
'<button needs-scroll>Hello!</button>' +
|
||||
'</ion-nav-buttons>' +
|
||||
'</ion-content>' +
|
||||
'</ion-view>' +
|
||||
'</div>')($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
expect(el.find('ion-content').children().scope())
|
||||
.toBe(el.find('.left-buttons button').scope());
|
||||
|
||||
//Test if the button was compiled able to access the parents of ion-nav-buttons
|
||||
var scrollCtrl = el.find('ion-content').controller('$ionicScroll');
|
||||
expect(scrollCtrl).toBeTruthy();
|
||||
expect(el.find('button[needs-scroll]').data('scrollCtrl')).toBe(scrollCtrl);
|
||||
}));
|
||||
|
||||
it('should error without a parent ionNavBar', inject(function($compile, $rootScope) {
|
||||
expect(function() {
|
||||
$compile('<ion-nav-back-button>')($rootScope);
|
||||
|
||||
@@ -40,24 +40,27 @@ describe('ionView directive', function() {
|
||||
expect(el.controller('ionNavBar').changeTitle).toHaveBeenCalledWith('Hi, 1!', 'foo');
|
||||
});
|
||||
|
||||
it('should showBackButten depending on what is given', function() {
|
||||
var el = setup();
|
||||
it('should showBackButton depending on what is given', function() {
|
||||
var el = setup('hide-back-button="shouldHideBack"');
|
||||
expect(el.controller('ionNavBar').showBackButton).toHaveBeenCalledWith(true);
|
||||
el = setup('hide-back-button="true"');
|
||||
el.scope().$apply('shouldHideBack = true');
|
||||
expect(el.controller('ionNavBar').showBackButton).toHaveBeenCalledWith(false);
|
||||
el.scope().$apply('shouldHideBack = false');
|
||||
expect(el.controller('ionNavBar').showBackButton).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('should showBar depending on what is given', function() {
|
||||
var el = setup();
|
||||
var el = setup('hide-nav-bar="shouldHide"');
|
||||
expect(el.controller('ionNavBar').showBar).toHaveBeenCalledWith(true);
|
||||
var el = setup('hide-nav-bar="true"');
|
||||
el.scope().$apply('shouldHide = true');
|
||||
expect(el.controller('ionNavBar').showBar).toHaveBeenCalledWith(false);
|
||||
el.scope().$apply('shouldHide = false');
|
||||
expect(el.controller('ionNavBar').showBar).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('should setTitle on change', function() {
|
||||
var el = setup('', {title: 'foo'});
|
||||
expect(el.controller('ionNavBar').setTitle).not.toHaveBeenCalled();
|
||||
el.isolateScope().$apply('title = "bar"');
|
||||
expect(el.controller('ionNavBar').setTitle).toHaveBeenCalledWith('bar');
|
||||
var el = setup('title="{{something}}1"');
|
||||
el.scope().$apply('something = "bar"');
|
||||
expect(el.controller('ionNavBar').setTitle).toHaveBeenCalledWith('bar1');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<ion-view title="Sign-In">
|
||||
|
||||
<ion-nav-buttons side="left">
|
||||
<button class="button button-icon icon ion-home">
|
||||
<button class="button button-icon icon ion-home" ng-click="foo()">
|
||||
Home
|
||||
</button>
|
||||
</ion-nav-buttons>
|
||||
@@ -321,6 +321,10 @@
|
||||
})
|
||||
|
||||
.controller('SignInCtrl', function($scope, $state) {
|
||||
$scope.foo = function() {
|
||||
alert('foo');
|
||||
};
|
||||
|
||||
$scope.signIn = function(user) {
|
||||
$state.go('tabs.autolist');
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user