Skip to content

Commit

Permalink
fix(collectionRepeat): properly resize, but only when scrollView size…
Browse files Browse the repository at this point in the history
… actually changes

Closes #2935. Closes #3054.
  • Loading branch information
ajoslin committed Feb 9, 2015
1 parent ea912e8 commit b7a0968
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 41 deletions.
52 changes: 32 additions & 20 deletions js/angular/directive/collectionRepeat.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,38 +205,50 @@ function($collectionRepeatManager, $collectionDataSource, $parse) {
function rerender(value) {
var beforeSiblings = [];
var afterSiblings = [];
var collectionRepeatNode = $element[0];
var before = true;
var children = scrollViewContent.children;
var width, height, el, child;

forEach(scrollViewContent.children, function(node, i) {
if (ionic.DomUtil.elementIsDescendant($element[0], node, scrollViewContent)) {
// Loop through all of the children of scrollViewContent. Put every child BEFORE
// the collectionRepeatNode in `beforeSiblings`, and all of the children AFTER
// the collectionRepeatNode in `afterSiblings`.
for (var i = 0; child = children[i]; i++) {
if (child.hasAttribute('collection-repeat-ignore')) continue;
if (child.contains(collectionRepeatNode)) {
// Once we reach the collectionRepeatNode, we're now counting siblings AFTER the repeater.
before = false;
} else {
if (node.hasAttribute('collection-repeat-ignore')) return;
var width = node.offsetWidth;
var height = node.offsetHeight;
if (width && height) {
var element = jqLite(node);
(before ? beforeSiblings : afterSiblings).push({
width: node.offsetWidth,
height: node.offsetHeight,
element: element,
scope: element.isolateScope() || element.scope(),
isOutside: true
});
}
continue;
}
});
if ( (width = child.offsetWidth) && (height = child.offsetHeight) ) {
(before ? beforeSiblings : afterSiblings).push({
width: width,
height: height,
element: (el = jqLite(child)),
scope: el.isolateScope() || el.scope(),
isOutside: true
})
}
}

scrollView.resize();
dataSource.setData(value, beforeSiblings, afterSiblings);
collectionRepeatManager.resize();
}

var requiresRerender;
var lastDim = {};
var newDim = {};
function rerenderOnResize() {
if ($scope.$$disconnected) return;
rerender(listExprParsed($scope));
requiresRerender = (!scrollViewContent.clientWidth && !scrollViewContent.clientHeight);
newDim = {
width: scrollViewContent.clientWidth,
height: scrollViewContent.clientHeight
};
if (!angular.equals(lastDim, newDim) && !$scope.$$disconnected) {
rerender(listExprParsed($scope));
}
requiresRerender = (!newDim.width && !newDim.height);
lastDim = newDim;
}

function viewEnter() {
Expand Down
45 changes: 25 additions & 20 deletions js/angular/service/collectionRepeatManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,27 @@ function($rootScope, $timeout) {
* vertically: Items are laid out with primarySize being height,
* secondarySize being width.
*/
var self = this;
var primaryPos = 0;
var secondaryPos = 0;
var secondaryScrollSize = this.secondaryScrollSize();
var secondaryScrollSize = self.secondaryScrollSize();
var previousItem;
var i, len;

this.dataSource.beforeSiblings && this.dataSource.beforeSiblings.forEach(calculateSize, this);
var beforeSize = primaryPos + (previousItem ? previousItem.primarySize : 0);
// Skip past every beforeSibling, we want our list to start after those.
for (i = 0, len = (self.dataSource.beforeSiblings || []).length; i < len; i++) {
calculateSize(self.dataSource.beforeSiblings[i]);
}
var beforeSize = primaryPos + (previousItem && previousItem.primarySize || 0);

primaryPos = secondaryPos = 0;
previousItem = null;

var dimensions = this.dataSource.dimensions.map(calculateSize, this);
var totalSize = primaryPos + (previousItem ? previousItem.primarySize : 0);
var dimensions = [];
for (i = 0, len = self.dataSource.dimensions.length; i < len; i++) {
dimensions.push( calculateSize(self.dataSource.dimensions[i]) );
}
var totalSize = primaryPos + (previousItem && previousItem.primarySize || 0);

return {
beforeSize: beforeSize,
Expand All @@ -121,12 +129,12 @@ function($rootScope, $timeout) {
//the dataSource
var rect = {
//Get the height out of the dimension object
primarySize: this.primaryDimension(dim),
primarySize: self.primaryDimension(dim),
//Max out the item's width to the width of the scrollview
secondarySize: Math.min(this.secondaryDimension(dim), secondaryScrollSize)
secondarySize: Math.min(self.secondaryDimension(dim), secondaryScrollSize)
};

//If this isn't the first item
//If self isn't the first item
if (previousItem) {
//Move the item's x position over by the width of the previous item
secondaryPos += previousItem.secondarySize;
Expand All @@ -147,6 +155,7 @@ function($rootScope, $timeout) {
return rect;
}
},

resize: function() {
var result = this.calculateDimensions();
this.dimensions = result.dimensions;
Expand Down Expand Up @@ -217,15 +226,16 @@ function($rootScope, $timeout) {
* to fully optimize it.
*/
getIndexForScrollValue: function(i, scrollValue) {
var dimensions = this.dimensions;
var rect;
//Scrolling up
if (scrollValue <= this.dimensions[i].primaryPos) {
while ( (rect = this.dimensions[i - 1]) && rect.primaryPos > scrollValue) {
if (scrollValue <= dimensions[i].primaryPos) {
while ( (rect = dimensions[i - 1]) && rect.primaryPos > scrollValue) {
i--;
}
//Scrolling down
} else {
while ((rect = this.dimensions[i + 1]) && rect.primaryPos < scrollValue) {
while ((rect = dimensions[i + 1]) && rect.primaryPos < scrollValue) {
i++;
}
}
Expand Down Expand Up @@ -279,15 +289,10 @@ function($rootScope, $timeout) {
doRender(i, rect);
i++;
}

// Render two extra items at the end as a buffer
if (self.dimensions[i]) {
doRender(i, self.dimensions[i]);
i++;
}
if (self.dimensions[i]) {
doRender(i, self.dimensions[i]);
}
if ( (rect = self.dimensions[i]) ) doRender(i++, rect);
if ( (rect = self.dimensions[i]) ) doRender(i, rect);

var renderEndIndex = i;

// Remove any items that were rendered and aren't visible anymore
Expand Down Expand Up @@ -318,7 +323,7 @@ function($rootScope, $timeout) {
primaryPos, secondaryPos
));
item.primaryPos = primaryPos;
item.secondaryPos = secondaryPos;
item.secondaryPos = secondaryPos
}

var width = this.isVertical ? itemDimensions.secondarySize : itemDimensions.primarySize;
Expand Down
9 changes: 8 additions & 1 deletion test/html/list-fit.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ <h1 class="title">Hi</h1>
<a class="button" ng-click="scrollBottom(true)">
Bottom
</a>
<a class="button" ng-click="openModal()">
MODAL
</a>
</ion-header-bar>
<ion-content>
<ion-refresher on-refresh="loadMore()"></ion-refresher>
Expand Down Expand Up @@ -44,7 +47,7 @@ <h2>{{item.text}}</h2>
</ion-content>
<script>
angular.module('ionic').controller('MainCtrl',MainCtrl)
function MainCtrl($scope, $ionicScrollDelegate, $timeout, $q, $ionicLoading) {
function MainCtrl($scope, $ionicScrollDelegate, $timeout, $q, $ionicLoading, $ionicModal) {
$scope.items = [];
function addImage() {
var i = $scope.items.length;
Expand All @@ -65,6 +68,10 @@ <h2>{{item.text}}</h2>
$scope.$broadcast('scroll.refreshComplete');
}, 1);
};

$scope.openModal = function() {
$ionicModal.fromTemplate('<ion-modal-view>hello</ion-modal-view>').show();
};
}
</script>
<style>
Expand Down

0 comments on commit b7a0968

Please sign in to comment.