mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(ionic): remove all delegates
BREAKING CHANGE: $ionicScrollDelegate, $ionicSlideBoxDelegate, and
$ionicSideMenuDelegate have been removed.
- $ionicScrollDelegate has been changed to $ionicScrollController.
Documentation:
[ionContent](
http://ajoslin.github.io/docs/nightly/api/directive/ionContent),
[ionScroll](
http://ajoslin.github.io/docs/nightly/api/directive/ionScroll)
Change your code from this:
```html
<ion-content ng-controller="MyCtrl">
<button ng-click="scrollBottom()">Scroll to bottom!</button>
</ion-content>
```
```js
function MyCtrl($scope, $ionicScrollDelegate) {
$scope.scrollBottom = function() {
$ionicScrollDelegate.scrollBottom();
};
}
```
To this:
```html
<!-- optional attr controller-bind, see docs -->
<ion-content ng-controller="MyCtrl">
<button ng-click="scrollBottom()">Scroll to bottom!</button>
</ion-content>
```
```js
function MyCtrl($scope) {
$scope.scrollBottom = function() {
$scope.$ionicScrollController.scrollBottom();
};
}
```
- $ionicSideMenuDelegate has been changed to
$ionicSideMenusController. Documentation:
[ionSideMenus](http://ajoslin.github.io/docs/nightly/api/directive/ionSideMenus)
Change your code from this:
```html
<ion-side-menus>
<ion-side-menu side="left">Side Menu Left</ion-side-menu>
<ion-pane ion-side-menu-content ng-controller="MyCtrl">
<button ng-click="toggleLeftMenu()">
Toggle Left Menu!
</button>
</ion-pane>
</ion-side-menus>
```
```js
function MyCtrl($scope, $ionicSideMenuDelegate) {
$scope.toggleLeftMenu = function() {
$ionicSideMenuDelegate.toggleLeft();
};
}
```
To this:
```html
<!-- optional attr controller-bind, see documentation -->
<ion-side-menus>
<ion-side-menu side="left">Side Menu Left</ion-side-menu>
<ion-pane ion-side-menu-content ng-controller="MyCtrl">
<button ng-click="toggleLeftMenu()">
Toggle Left Menu!
</button>
</ion-pane>
</ion-side-menus>
```
```js
function MyCtrl($scope) {
$scope.toggleLeftMenu = function() {
$scope.$ionicSideMenuController.toggleLeft();
};
}
```
- $ionicSlideBoxDelegate has been removed and upgraded to
$ionicSlideBoxController. It had only one method that
was unneeded. [Documentation](
http://ajoslin.github.io/docs/nightly/api/directive/ionSlideBox)
This commit is contained in:
@@ -10,6 +10,7 @@ describe('$ionicScroll Controller', function() {
|
||||
//scrollView requires an outer container element and a child
|
||||
//content element
|
||||
angular.element('<div><div></div></div>')[0];
|
||||
angular.element('<div>').append(options.el);
|
||||
|
||||
inject(function($controller, $rootScope, $timeout) {
|
||||
scope = $rootScope.$new();
|
||||
@@ -22,15 +23,35 @@ describe('$ionicScroll Controller', function() {
|
||||
});
|
||||
}
|
||||
|
||||
it('should set this.$scope', function() {
|
||||
setup();
|
||||
//Just an arbitrary way of checking that it is indeed a scope
|
||||
expect(typeof ctrl.$scope.$id).toBe('string');
|
||||
it('should set $scope.$ionicScrollController by default', function() {
|
||||
setup()
|
||||
expect(scope.$ionicScrollController).toBe(ctrl);
|
||||
});
|
||||
|
||||
it('should set $scope.$$ionicScrollController', function() {
|
||||
it('should set options.controllerBind to ctrl', function() {
|
||||
setup({
|
||||
controllerBind: 'something'
|
||||
});
|
||||
expect(scope.something).toBe(ctrl);
|
||||
});
|
||||
|
||||
it('should set bounce to !isAndroid after platformReady, if not options.boucing', function() {
|
||||
var isAndroid;
|
||||
spyOn(ionic.Platform, 'isAndroid').andCallFake(function() {
|
||||
return isAndroid;
|
||||
});
|
||||
setup({
|
||||
bouncing: true
|
||||
});
|
||||
expect(ionic.Platform.isAndroid).not.toHaveBeenCalled();
|
||||
|
||||
isAndroid = true;
|
||||
setup();
|
||||
expect(ctrl.$scope.$$ionicScrollController).toBe(ctrl);
|
||||
expect(ctrl.scrollView.options.bouncing).toBe(false);
|
||||
|
||||
isAndroid = false;
|
||||
setup();
|
||||
expect(ctrl.scrollView.options.bouncing).toBe(true);
|
||||
});
|
||||
|
||||
it('should set this.element and this.$element', function() {
|
||||
@@ -46,7 +67,7 @@ describe('$ionicScroll Controller', function() {
|
||||
|
||||
it('should register controller on element.data', function() {
|
||||
setup();
|
||||
expect(ctrl.$element.controller('$ionicScroll')).toBe(ctrl);
|
||||
expect(ctrl.$element.parent().data('$$ionicScrollController')).toBe(ctrl);
|
||||
});
|
||||
|
||||
it('should run after a timeout', function() {
|
||||
@@ -64,24 +85,57 @@ describe('$ionicScroll Controller', function() {
|
||||
});
|
||||
|
||||
it('should remember scroll position on $viewContentLoaded event', function() {
|
||||
var historyData = { rememberedScrollValues: { left: 1, top: 2 } };
|
||||
var historyData = { viewId: '1' };
|
||||
setup();
|
||||
spyOn(ctrl.scrollView, 'scrollTo');
|
||||
spyOn(ctrl, 'rememberScrollPosition');
|
||||
spyOn(ctrl, 'scrollToRememberedPosition');
|
||||
scope.$broadcast('$viewContentLoaded', historyData);
|
||||
timeout.flush();
|
||||
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(1, 2);
|
||||
expect(ctrl.rememberScrollPosition).toHaveBeenCalledWith('1');
|
||||
expect(ctrl.scrollToRememberedPosition).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should forget on $viewHistory.viewBack after $viewContentLoaded', inject(function($rootScope) {
|
||||
var historyData = { viewId: 'foo' };
|
||||
setup();
|
||||
spyOn($rootScope, '$on').andCallThrough();;
|
||||
scope.$broadcast('$viewContentLoaded', historyData);
|
||||
expect(scope.$on).toHaveBeenCalledWith('$viewHistory.viewBack', jasmine.any(Function));
|
||||
|
||||
//Should not forget unless backViewId is the same
|
||||
spyOn(ctrl, 'forgetScrollPosition');
|
||||
$rootScope.$broadcast('$viewHistory.viewBack', 'bar');
|
||||
expect(ctrl.forgetScrollPosition).not.toHaveBeenCalled();
|
||||
$rootScope.$broadcast('$viewHistory.viewBack', 'foo');
|
||||
expect(ctrl.forgetScrollPosition).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should not remember scrollValues on $destroy without id', inject(function($$scrollValueCache) {
|
||||
setup();
|
||||
spyOn(ctrl.scrollView, 'getValues');
|
||||
scope.$destroy();
|
||||
expect(ctrl.scrollView.getValues).not.toHaveBeenCalled();
|
||||
expect($$scrollValueCache).toEqual({});
|
||||
}));
|
||||
|
||||
it('should remember scrollValues on $destroy with id', inject(function($$scrollValueCache) {
|
||||
setup();
|
||||
ctrl.rememberScrollPosition('super');
|
||||
spyOn(ctrl.scrollView, 'getValues').andCallFake(function() {
|
||||
return {
|
||||
left: 33,
|
||||
top: 44
|
||||
};
|
||||
return 'scrollValues';
|
||||
});
|
||||
scope.$broadcast('$destroy');
|
||||
expect(historyData.rememberedScrollValues).toEqual({
|
||||
left: 33,
|
||||
top: 44
|
||||
scope.$destroy();
|
||||
expect(ctrl.scrollView.getValues).toHaveBeenCalled();
|
||||
expect($$scrollValueCache).toEqual({
|
||||
'super': 'scrollValues'
|
||||
});
|
||||
}));
|
||||
|
||||
it('rememberScrollPosition should throw without id', function() {
|
||||
setup();
|
||||
expect(function() {
|
||||
ctrl.rememberScrollPosition();
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should unbind window event listener on scope destroy', function() {
|
||||
@@ -95,12 +149,119 @@ describe('$ionicScroll Controller', function() {
|
||||
expect(window.removeEventListener.mostRecentCall.args[0]).toBe('resize');
|
||||
});
|
||||
|
||||
it('should register with $ionicScrollDelegate', inject(function($ionicScrollDelegate) {
|
||||
spyOn($ionicScrollDelegate, 'register');
|
||||
it('rememberScrollPosition should set id', function() {
|
||||
setup();
|
||||
expect($ionicScrollDelegate.register).toHaveBeenCalledWith(scope, ctrl.$element, ctrl.scrollView);
|
||||
expect(ctrl._rememberScrollId).toBeFalsy();
|
||||
ctrl.rememberScrollPosition('banana');
|
||||
expect(ctrl._rememberScrollId).toBe('banana');
|
||||
});
|
||||
|
||||
it('forgetScrollPosition should remove from cache and unset id', inject(function($$scrollValueCache) {
|
||||
setup();
|
||||
ctrl._rememberScrollId = 'elephant';
|
||||
$$scrollValueCache.elephant = 'stampede';
|
||||
ctrl.forgetScrollPosition();
|
||||
expect(ctrl._rememberScrollId).toBeFalsy();
|
||||
expect($$scrollValueCache.elephant).toBeFalsy();
|
||||
}));
|
||||
|
||||
it('should listen to scroll event and call $onScroll', function() {
|
||||
setup();
|
||||
scope.$onScroll = jasmine.createSpy();
|
||||
|
||||
expect(scope.$onScroll).not.toHaveBeenCalled();
|
||||
|
||||
ionic.trigger('scroll', {target: ctrl.element});
|
||||
expect(scope.$onScroll).toHaveBeenCalled();
|
||||
expect(scope.$onScroll.mostRecentCall.args[0].scrollLeft).toBe(0);
|
||||
expect(scope.$onScroll.mostRecentCall.args[0].scrollTop).toBe(0);
|
||||
|
||||
scope.$onScroll.reset();
|
||||
ionic.trigger('scroll', {target: ctrl.element, scrollTop: 3, scrollLeft: 4});
|
||||
expect(scope.$onScroll.mostRecentCall.args[0].scrollLeft).toBe(4);
|
||||
expect(scope.$onScroll.mostRecentCall.args[0].scrollTop).toBe(3);
|
||||
});
|
||||
|
||||
it('.resize() should resize after timeout', inject(function($timeout) {
|
||||
setup();
|
||||
$timeout.flush();
|
||||
spyOn(ctrl.scrollView, 'resize');
|
||||
ctrl.resize();
|
||||
expect(ctrl.scrollView.resize).not.toHaveBeenCalled();
|
||||
$timeout.flush();
|
||||
expect(ctrl.scrollView.resize).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
[false, true].forEach(function(shouldAnimate) {
|
||||
describe('with animate='+shouldAnimate, function() {
|
||||
|
||||
it('scrollToRememberedPosition should work', inject(function($$scrollValueCache) {
|
||||
setup();
|
||||
spyOn(ctrl.scrollView, 'scrollTo');
|
||||
$$scrollValueCache.foo = { left: 3, top: 4 };
|
||||
ctrl._rememberScrollId = 'foo';
|
||||
expect(ctrl.scrollView.scrollTo).not.toHaveBeenCalled();
|
||||
ctrl.scrollToRememberedPosition(shouldAnimate);
|
||||
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(3, 4, shouldAnimate);
|
||||
}));
|
||||
|
||||
describe('scroll action', function() {
|
||||
beforeEach(function() {
|
||||
setup();
|
||||
//Mock resize to insta-call through for easier tests
|
||||
ctrl.resize = function() {
|
||||
return { then: function(cb) { cb(); } };
|
||||
};
|
||||
});
|
||||
it('.scrollTop', function() {
|
||||
spyOn(ctrl.scrollView, 'scrollTo');
|
||||
ctrl.scrollTop(shouldAnimate);
|
||||
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(0, 0, shouldAnimate);
|
||||
});
|
||||
it('.scrollBottom', function() {
|
||||
spyOn(ctrl.scrollView, 'scrollTo');
|
||||
spyOn(ctrl.scrollView, 'getScrollMax').andCallFake(function() {
|
||||
return { left: 33, top: 44 };
|
||||
});
|
||||
ctrl.scrollBottom(shouldAnimate);
|
||||
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(33, 44, shouldAnimate);
|
||||
});
|
||||
it('.scrollTo', function() {
|
||||
spyOn(ctrl.scrollView, 'scrollTo');
|
||||
ctrl.scrollTo(1, 2, shouldAnimate);
|
||||
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(1, 2, shouldAnimate);
|
||||
});
|
||||
it('.anchorScroll without hash should scrollTop', inject(function($location, $document) {
|
||||
$document[0].getElementById = jasmine.createSpy();
|
||||
$location.hash = function() { return null; };
|
||||
spyOn(ctrl.scrollView, 'scrollTo');
|
||||
ctrl.anchorScroll(shouldAnimate);
|
||||
expect($document[0].getElementById).not.toHaveBeenCalled();
|
||||
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(0, 0, shouldAnimate);
|
||||
}));
|
||||
it('.anchorScroll with hash but no element should scrollTop', inject(function($location, $document) {
|
||||
$document[0].getElementById = jasmine.createSpy();
|
||||
$location.hash = function() { return 'foo'; };
|
||||
spyOn(ctrl.scrollView, 'scrollTo');
|
||||
ctrl.anchorScroll(shouldAnimate);
|
||||
expect($document[0].getElementById).toHaveBeenCalledWith('foo');
|
||||
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(0, 0, shouldAnimate);
|
||||
}));
|
||||
it('.anchorScroll with el matching hash should scroll to it', inject(function($location, $document) {
|
||||
$document[0].getElementById = jasmine.createSpy('byId').andCallFake(function() {
|
||||
return { offsetLeft: 8, offsetTop: 9 };
|
||||
});
|
||||
spyOn($location, 'hash').andCallFake(function() {
|
||||
return 'foo';
|
||||
});
|
||||
spyOn(ctrl.scrollView, 'scrollTo');
|
||||
ctrl.anchorScroll(shouldAnimate);
|
||||
expect(ctrl.scrollView.scrollTo).toHaveBeenCalledWith(8, 9, shouldAnimate);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not activatePullToRefresh if setRefresher is not called', function() {
|
||||
setup();
|
||||
timeout.flush();
|
||||
@@ -119,7 +280,7 @@ describe('$ionicScroll Controller', function() {
|
||||
refreshingCb = refreshing;
|
||||
doneCb = done;
|
||||
});
|
||||
ctrl.setRefresher(scope, ctrl.element);
|
||||
ctrl._setRefresher(scope, ctrl.element);
|
||||
|
||||
var scrollOnRefreshSpy = jasmine.createSpy('scroll.onRefresh');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user