From 01c829c35114a655e50e98d46e3b03f72364c13f Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 9 Oct 2014 08:39:45 -0600 Subject: [PATCH] feat(slideBox): use `selected` value provided for initial section Addresses #2288. --- js/angular/controller/slideBoxController.js | 37 +++++++++++--------- js/angular/directive/slideBox.js | 11 +++--- js/angular/main.js | 1 + test/html/slideBox.html | 4 +-- test/unit/angular/directive/slideBox.unit.js | 27 +++++++++++--- 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/js/angular/controller/slideBoxController.js b/js/angular/controller/slideBoxController.js index 6602e9c7ae..e491d7200d 100644 --- a/js/angular/controller/slideBoxController.js +++ b/js/angular/controller/slideBoxController.js @@ -11,7 +11,6 @@ IonicModule function(scope, element, $$ionicAttachDrag, $interval) { var self = this; var slideList = ionic.Utils.list([]); - var selectedIndex = -1; var slidesParent = angular.element(element[0].querySelector('.slider-slides')); // Successful slide requires velocity to be greater than this amount @@ -54,24 +53,23 @@ function(scope, element, $$ionicAttachDrag, $interval) { // Gets whether the given index is relevant to selected // That is, whether the given index is previous, selected, or next function isRelevant(index) { - return slideList.isRelevant(index, selectedIndex); + return slideList.isRelevant(index, scope.selectedIndex); } - // Gets the index to the previous of the given slide, default selectedIndex + // Gets the index to the previous of the given slide, default scope.selectedIndex function previous(index) { - index = arguments.length ? index : selectedIndex; + index = arguments.length ? index : scope.selectedIndex; // If we only have two slides and loop is enabled, we cannot have a previous // because previous === next. In this case, return -1. if (self.loop() && self.count() === 2) { - console.log('lying about previous'); return -1; } return slideList.previous(index); } - // Gets the index to the next of the given slide, default selectedIndex + // Gets the index to the next of the given slide, default scope.selectedIndex function next(index) { - index = arguments.length ? index : selectedIndex; + index = arguments.length ? index : scope.selectedIndex; return slideList.next(index); } @@ -99,7 +97,12 @@ function(scope, element, $$ionicAttachDrag, $interval) { var newIndex = slideList.add(slide, index); slide.onAdded(slidesParent); - if (selectedIndex === -1) { + // If we are waiting for a certain scope.selectedIndex and this is it, + // select the slide + if (scope.selectedIndex === index) { + self.select(newIndex); + // If we don't have a selectedIndex yet, select the first one available + } else if (!isNumber(scope.selectedIndex) || scope.selectedIndex === -1) { self.select(newIndex); } else if (newIndex === self.previous() || newIndex === self.next()) { // if the new slide is adjacent to selected, refresh the selection @@ -115,7 +118,7 @@ function(scope, element, $$ionicAttachDrag, $interval) { slide.onRemoved(); if (isSelected) { - self.select( self.isInRange(selectedIndex) ? selectedIndex : selectedIndex - 1 ); + self.select( self.isInRange(scope.selectedIndex) ? scope.selectedIndex : scope.selectedIndex - 1 ); } } function move(slide, targetIndex) { @@ -133,7 +136,7 @@ function(scope, element, $$ionicAttachDrag, $interval) { } function selected() { - return selectedIndex; + return self.isInRange(scope.selectedIndex) ? scope.selectedIndex : -1; } /* @@ -142,15 +145,15 @@ function(scope, element, $$ionicAttachDrag, $interval) { function select(newIndex, transitionDuration) { if (!self.isInRange(newIndex)) return; - var delta = self.delta(selectedIndex, newIndex); + var delta = self.delta(scope.selectedIndex, newIndex); slidesParent.css( ionic.CSS.TRANSITION_DURATION, (transitionDuration || SLIDE_TRANSITION_DURATION) + 'ms' ); - selectedIndex = newIndex; + scope.selectedIndex = newIndex; - if (self.isInRange(selectedIndex) && Math.abs(delta) > 1) { + if (self.isInRange(scope.selectedIndex) && Math.abs(delta) > 1) { // if the new slide is > 1 away, then it is currently not attached to the DOM. // Attach it in the position from which it will slide in. self.at(newIndex).setState(delta > 1 ? 'next' : 'previous'); @@ -163,9 +166,9 @@ function(scope, element, $$ionicAttachDrag, $interval) { function doSelect() { // If a new selection has happened before this frame, abort. - if (selectedIndex !== newIndex) return; + if (scope.selectedIndex !== newIndex) return; scope.$evalAsync(function() { - if (selectedIndex !== newIndex) return; + if (scope.selectedIndex !== newIndex) return; arrangeSlides(newIndex); }); } @@ -197,7 +200,7 @@ function(scope, element, $$ionicAttachDrag, $interval) { ); self.select(nextIndex, transitionDuration); } else { - self.select(selectedIndex); + self.select(scope.selectedIndex); } } @@ -257,7 +260,7 @@ function(scope, element, $$ionicAttachDrag, $interval) { if (!enqueueRefresh.queued) { enqueueRefresh.queued = true; scope.$$postDigest(function() { - self.select(selectedIndex); + self.select(scope.selectedIndex); enqueueRefresh.queued = false; }); } diff --git a/js/angular/directive/slideBox.js b/js/angular/directive/slideBox.js index ca43d984f3..b538b3f47c 100644 --- a/js/angular/directive/slideBox.js +++ b/js/angular/directive/slideBox.js @@ -97,18 +97,15 @@ function($ionicSlideBoxDelegate, $window) { } function watchSelected() { - scope.$watch('selectedIndex', function selectedAttrWatchAction(newIndex) { + scope.$watch('selectedIndex', function selectedAttrWatchAction(newIndex, oldIndex) { if (slideBoxCtrl.isInRange(newIndex) && slideBoxCtrl.selected() !== newIndex) { slideBoxCtrl.select(newIndex); + scope.onSlideChanged({ + $index: newIndex + }); } }); - scope.$watch(slideBoxCtrl.selected, function shownWatchAction(newIndex) { - scope.selectedIndex = newIndex; - scope.onSlideChanged({ - $index: newIndex - }); - }); } function watchAutoPlay() { diff --git a/js/angular/main.js b/js/angular/main.js index ce813cd142..0f4e0bbd95 100644 --- a/js/angular/main.js +++ b/js/angular/main.js @@ -2,6 +2,7 @@ var IonicModule = angular.module('ionic', ['ngAnimate', 'ngSanitize', 'ui.router extend = angular.extend, forEach = angular.forEach, isDefined = angular.isDefined, + isNumber = angular.isNumber, isString = angular.isString, jqLite = angular.element; diff --git a/test/html/slideBox.html b/test/html/slideBox.html index 1890f9e074..ec84422c4a 100644 --- a/test/html/slideBox.html +++ b/test/html/slideBox.html @@ -41,7 +41,7 @@ } - +
@@ -94,7 +94,7 @@ .controller('SlideCtrl', function($scope, $timeout) { $scope.items = []; - for (var i = 0; i < 1000; i++) { + for (var i = 0; i < 50; i++) { $scope.items.push(i); } diff --git a/test/unit/angular/directive/slideBox.unit.js b/test/unit/angular/directive/slideBox.unit.js index 4dc8aceee3..e61ec9393a 100644 --- a/test/unit/angular/directive/slideBox.unit.js +++ b/test/unit/angular/directive/slideBox.unit.js @@ -13,7 +13,7 @@ describe('ionSlideBox directive', function() { return el.find('ion-slide-box'); } - it('should bind to selected attr', inject(function($rootScope, $timeout) { + it('should bind to select - > selected attr', inject(function($rootScope, $timeout) { var slideBox = makeSlideBox('' + 'A' + 'B' + @@ -33,12 +33,31 @@ describe('ionSlideBox directive', function() { $timeout.flush(); expect($rootScope.currentIndex).toBe(1); - // No out of bounds + // Out of bounds should apply expect(slideBoxCtrl.selected()).toBe(1); $rootScope.$apply('currentIndex = -1'); - expect(slideBoxCtrl.selected()).toBe(1); + expect(slideBoxCtrl.selected()).toBe(-1); $rootScope.$apply('currentIndex = 3'); - expect(slideBoxCtrl.selected()).toBe(1); + expect(slideBoxCtrl.selected()).toBe(-1); + })); + + it('should bind to selected attr to slide', inject(function($rootScope, $timeout) { + $rootScope.currentIndex = 2; + var slideBox = makeSlideBox('' + + 'A' + + 'B' + + 'C' + + ''); + + var slideBoxCtrl = slideBox.controller('ionSlideBox'); + + expect(slideBoxCtrl.selected()).toBe(2); + expect($rootScope.currentIndex).toBe(2); + $timeout.flush(); + + slideBoxCtrl.select(1); + $timeout.flush(); + expect($rootScope.currentIndex).toBe(1); })); it('should loop depending on attr.loop', inject(function($rootScope) {