kamilkp / angular-vs-repeat Goto Github PK
View Code? Open in Web Editor NEWVirtual Scroll for AngularJS ngRepeat directive
Home Page: http://kamilkp.github.io/angular-vs-repeat/
License: MIT License
Virtual Scroll for AngularJS ngRepeat directive
Home Page: http://kamilkp.github.io/angular-vs-repeat/
License: MIT License
Hi!
I would like to see a released version.
Thank you!
have you used it with this library:
http://manos.malihu.gr/jquery-custom-content-scroller/
because this library uses the height of its list to set the scrolling area, and your library uses the height, to limit it.
I have something that looks like this:
<ul vs-repeat>
<li my-custom-directive="items"></li>
</ul>
my-custom-directive
looks like this:
angular.module('my.module').directive('myCustomDirective', function myCustomDirective() {
return {
template: [
'<li ng-repeat="item in items">',
'{{item}}',
'</li>'
].join(' '),
replace: true,
scope: {
items: '=myCustomDirective'
}
}
});
Because the ng-repeat
is "hidden" inside the template of my-custom-directive
I get this error:
TypeError: Cannot read property '1' of null
because expressionMatches
is an empty array (because ngRepeatExpression
is undefined, because ngRepeatChild
doesn't have an ng-repeat
directive yet...)
I was looking at how to resolve this, but I'm not certain of the best way to go about it. I believe this could be a relatively common use case. What do you think?
First of all, thanks for this wonderful directive!
It would be great if it could use the size defined in vs-repeat
if the current item does not contain the vs-size-property
.
$scope.sizes = originalCollection.map(function(item){
return item[$attrs.vsSizeProperty] || $scope.elementSize; //# Line 165
});
Hi,
Thanks alot for creating such a wonderful directive.
I need your help in supporting the tile view with the ng-repeat. Please share your idea how and where i should do the modification to support the same.
Thanks
Are there any solutions to get inertial scrolling working on iOS?
This is a common workaround to the inertial scroll issue when overflow-y scrolling in a container, but this does not work with vs-repeat. The elements will only render after the momentum scroll has come to a complete stop.
You can observe this behavior here by swiping quick on your iOS device.
http://kamilkp.github.io/angular-vs-repeat/#?tab=2
Love your plugin and would be awesome if you knew solution for this!
Is there a way to get this to work with elements that are part of a ng-repeat-start / ng-repeat-end block? If I'm understanding the code correct, it's looking for "ng-repeat" specifically, and it bombs out if it doesn't find that specific attribute with this error (line 99 of unminified v1.0.0-rc5 js):
TypeError: Cannot read property '1' of null
In the latest release (v1.0.0rc9), the vs-scroll-parent functionality is broken. When I scroll, the virtualized elements are translated down out of the viewable area. I have created a codepen to show the problem:
Good Afternoon,
I am loving vs-repeat so far, however I ran into an issue when resizing. When I resize the browser, vs-repeat seems to not be recalculating the heights and offsets. The element sizes are all equal, but may change depending on the current browser window size.
Thanks in advance for looking into this.
When I remove an item from the list, the lists flickers.
If it could be possible, to have different li heights in the list. I know that it is one of limitations, but this would be really ql to have.
Please if you can help me i am always find this error Cannot read property '1' of null and i don't know why
Hello!
First of all, thanks for this wonderful directive, helped me a lot with my DOM memory management.
But I have a question, regarding the starting point of where the view gets rendered.
Is there a way I can set a starting point where my view gets rendered?
Let's say our ng-repeat has to iterate over a 100 elements in a scrollable view, now the elements get rendered from 1 to 100 on the screen. Well, I want to see the elements starting from 20 visible, and 1-19 visible when I scroll up. Is there a way I can do this?
Thanks!
Is there any plans to make it work with a grid-layout on the repeated items?
Seems like the translationY breaks the grid;
http://codepen.io/anon/pen/VYvmQN?editors=100
Hello,
I use angular-vs-repeat in horizontal mode, and I have a use-case where a column size can be changed (to show additional data on demand). I was expecting that the combination of vs-size-property="propertyName"
and $rootScope.$broadcast('vsRepeatTrigger');
would do the trick. But it seems that the reinitialization does not include re-computing sizes.
In addition to that I noticed that resizing a column, and then removing another column breaks everything.
Here's a plunkr showcasing both issue: http://plnkr.co/edit/wdl5JW7Ki1EE7t1kdthd?p=preview
Would it be possible to include re-computing size when re-initializing ? I had a look at the code but could not quite figure it out yet. Any help would be appreciated
Would be great if we had a method to get all items visible in viewport (including items in vs-excess)? I'm looking to filter the items on the screen first, then filter rest of array for quicker UI updates.
Thanks!
I'm attempting to use vs-excess in order to ensure enough items are in DOM to work around the virtual momentum scrolling issue. #40
Problem is, vs-excess is just not doing it's job. No excess items are ever in DOM. Ideas?
<!--GRID VIEW-->
<div vs-repeat class="inner-container" vs-excess="50" vs-size-property="rowHeight" vs-offset-before="77" on-vs-index-change="infiniteScroll(startIndex, endIndex)" ng-show="views.gridView">
<div ng-repeat="row in results.gridRows" style="width: 100%;">
<div ng-repeat="result in row.rowContents"
ng-click="openSplash(this)"
class="grid-item"
style="width: {{results.gridPercentageWidth}}%;"
>
//Add html here
</div>
</div>
</div>
factory.generateRows = function (results, reason, views) {
var numColumns;
//If user has gridView enabled calculate columns, else build list view.
if (views.gridView) {
var dimensions = factory.getInnerContainerDimensions();
var itemWidth = 290;
//console.log('width: ' + dimensions.w + '/' + itemWidth + ' equals...');
numColumns = Math.floor(dimensions.w / itemWidth);
factory.results.gridPercentageWidth = 100 / numColumns;
//console.log("Calculated " + numColumns + " columns at " + factory.results.gridPercentageWidth + "% width.");
} else {
numColumns = 1;
//console.log("List View: " + numColumns + " columns!");
}
if (numColumns !== factory.cachedColumnCalculation || reason === 'filter' || reason === 'pagination') {
factory.cachedColumnCalculation = numColumns;
//TODO: Don't clear all items just clear necessary ones??
factory.results.gridRows = [];
//Calculate the number of results with images and add up scroll height. This is used for virtual scrolling
for (var i = 0; i < results.length; i++) {
var rowHeight;
//If gridview is turned on they height is always 350
if (views.gridView) {
rowHeight = 390;
} else { //else the user is in list view. Height depends on whether result contains 2 or more images.
if(results[i].images.length === 0) {
rowHeight = 179;
} else if (results[i].images.length === 1) {
rowHeight = 261;
} else {
rowHeight = 420;
}
}
if (i % numColumns === 0) {
var row = {
rowHeight: rowHeight,
rowContents: []
};
for (var j = 0; j < numColumns; j++) {
if (i + j < results.length) {
//console.log(i + j);
if (results[i + j].askingPrice.value) {
factory.updatePriceSlider(results[i + j].askingPrice.value);
}
row.rowContents.push(results[i + j]);
}
}
factory.results.gridRows.push(row);
i = i + j - 1;
//console.log('Finshed row! New index is: ' + i);
}
}
console.log('Grid Rows: ', factory.results.gridRows);
}
};
Why not use $digest in scroll, it is faster then $apply, but you cannot use the new setting latch, because that slows it down.
if (updateInnerCollection()) {
$scope.$digest();
// $scope.$apply();
$scope.$broadcast('vsSetOffset-refresh');
}
I have a table, but it is not scrolled through with the default scrollbars, but the body scroll scrolls the table. Previously we had this large table appended in a div, and with some additional coding, we managed to scroll through the table with body scrollbars, because tables height was also body height.
Now that is not the case. Table has a static height, and after table is initialised, we set height of .vs-repeat-fill-element to body. How would we now scroll the table with body scrollbars? ... and also mouse wheel has to be included (scrolling on table, has to move scrollbars in body).
We would like to use native scrolling if possible. Any suggestions?
The demo doesn't work in IE (I tested on both 9 and 11). It seems to just display the last element in the list :(
Any chance of a fix?
My code :
<div class="items-list" id="tableSearchResults" data-auto-Scroll-Table vs-repeat="85" vs-excess="5">
<div class="request-row" ng-repeat="request in appData.favoriteDiamonds" ng-click="showItemDetails(request)">
$scope.removeDiamondFromFavorites = function(diamond){
if($scope.appData.favoriteDiamonds.indexOf(diamond) != -1){
var index = $scope.appData.favoriteDiamonds.indexOf(diamond);
$scope.appData.favoriteDiamonds.splice(index, 1);
}
}
When i remove item from list, it is also removed from the view and DOM element also removed from the view, but calculations (translateY) for the rest elements are not recalculated..
Example :
had originally 4 items,
deleted item number 2, result :
item1 - translateY(0) - wright
item2 - translateY(170) - wrong, must be 85
item3 - translateY(265) - wrong, must be 170
Any thoughts?
When using new option, the jumps are bigger and sometimes they happen, after user stops scrolling.
I'm using ngInfiniteScroll. After loading next portion of list with $http I'm placing it not directly to items array, but instead in subarray:
$http.get('list', {
params: {
offset: this.offset
}
}).then(function(data) {
this.items = this.items.concat([data.data.items]);
this.offset++;
this.busy = false;
}).bind(this));
In view I'm using one-time binding on subarray:
<div class="page-content" infinite-scroll="list.nextPage()" infinite-scroll-disabled="list.busy" infinite-scroll-distance="1">
<div class="row" ng-repeat="portion in list.items">
<div class="col-md-12" ng-repeat="item in ::portion">
</div>
</div>
<div ng-show="list.busy">Loading items...</div>
</div>
I think this trick makes vs-repeat benefitless for my case? Will I benefit from using vs-repeat?
If a block with vs-repeat is scrolled horizontally, vertical scroll is being reset to 0.
Please see the video: https://www.youtube.com/watch?v=EJ1RgXtJF2Q
Can easily reproduce using the latest Firefox on OS X Yosemite with a trackpad. This event always triggers every time this happens.
Hi, I've been searching for a solution to the poor performance loading of big DOMs on mobile browsers, especially in hybrid apps. I've been very enthusiastic about the angular-vs-repeat but maybe I'm doing something wrong, because whilst the DOM performance is much better, the scrolling became unusable. Am I doing something wrong? Can this be speeded up somehow? The mobile device is Android with Kitkat 4.4 and it is quite fast itself, but scrolling is now worse than with a simple ng-repeat. Do you have any ideas that could help?
Hello,
Which version of Angular is supported?
Kamilkp, thanks for this great directive. I was just wondering if it's possible to use filter(s) inside your vs-repeat directive?
I tried the example below, but the provided default, custom filters dont filter anything. When used without your directive it works fine.
<ul vs-repeat="120" vs-offset-after="6" class="repeater-container">
<li ng-repeat="item in items | filter:MyFilter | filter:query">
{{item.name}}
...
...
</li>
</ul>
Cool project. I'm thinking about using this for an infinite scrolling use case. However, for infinite scrolling, you don't have all the items upfront. I'd like to brainstorm with you on the best way we can support this use case. My service does tell me how many items I have in total upfront so I could provide that to angular-vs-repeat. Or I could fill in that many elements in my array and just have the extras be blank. What do you think a good infinite scrolling implementation would include when using angular-vs-repeat?
First off thanks, this is an awesome directive!
I have multiple vs-repeat
on the same page (10 at the moment and possibly more later) to create rows that infinitely scroll and display images. To help ensure that the images load before the user scrolls to elements off screen (especially on mobile), i have vs-access
set to 10. I've noticed that, due to my settings, if i add one time binding to the ng-style
attributes for childClone
, then it removes 16 watchers from each vs-repeat
- so 160 for the whole page.
So i was just wondering if this is something you'd be interested in adding if i submit a PR?
At the moment i'm just checking the minor version of angular that's being used to insure that it's 3 or greater, but i was also wondering if there's any reason why this should also be optional through an attribute? Is there any reason why this binding would need to be watched for changes?
I was looking for a library to make a horizontally scrollable box automatically scroll the active element into view and this here seemed like a great candidate for this task. Unfortunately I cannot seem to get it working.
The following error is logged when opening the page and similar ones when navigating with the buttons below the scrollable area:
TypeError: Cannot read property '1' of undefined
at updateInnerCollection (angular-vs-repeat.js:454)
at reinitialize (angular-vs-repeat.js:334)
at Object.fn (angular-vs-repeat.js:153)
at n.$digest (angular.js:14308)
at n.$apply (angular.js:14571)
at HTMLAnchorElement.<anonymous> (angular.js:21571)
at HTMLAnchorElement.c (angular.js:3032)
I am using the latest version from the master branch (f57eaa1).
It seems like it fails due to the $scope.sizesCumulative and/or $scope.sizes fields do not exists and I cannot seem to figure out why or how can I get them to work.
This seems to be a fairly new functionality and there aren't any examples around yet so maybe somebody can tell me where have I gone wrong?
Thanks!
Raido
seems like the vs-repeat cannot be used within another ng-repeat... i.e.
<div ng-repeat="setName in setNames">
<div class="repeater-container" vs-repeat="60">
<div class="item-element" ng-repeat="item in viewSet['set1']">{{item.text}</div>
</div>
</div>
here's a gist: https://gist.github.com/zippo445/6115fb8c65e00cb4a456 but it requires the 129a307 fix...
Hi,
Really like this module! I've been recommending it to people. Someone just reported to me that latest Chrome and Firefox are having troubles on the demo page. Everything seemed ok to me in Chrome, but latest Firefox does seem to have scrolling issues (the scrollbar worked, but mouse wheel scrolling did not).
Thanks for making this and sharing it!
newer version of the library does not support anchors in the repeated items as the vs-repeat-fill-element prevents you from being able to click on them. my workaround was just to give the fill-element a negative z-index.
Now you get the index of the item in current ng-repeat. Could we get also calculated index, depending on the startIndex.
Nothing is appended when using window as vsScrollParent.
I have tried using it on a table, but it didn't worked.
<tbody vs-repeat>
<tr ng-repeat..
Is this a known issue or?
Thanks
Hi,
I saw you've written all rendered elements must have the same height/width or the sizes of the elements must be known up front
.
Let's assume I have a treeview like this:
<div vs-repeat>
<div ng-repeat="parentNode in ParentNodes">
<bottuon ng-click="parentNode.open = !parentNode.open">Open</button>
<div ng-repeat="childNode in parentNodeChildren" ng-if="parentNode.open">
Bla Bla Bla
</div>
</div>
</div>
Could vs-repeat
handle the change in height? Is this in the to-do-list or is it a VI (virtuall impossible) task? I could try to take a shot at it if you direct me where to look in your code and think it's feasible.
There's an issue with repositioning elements in a vs-repeat list. The positions of other elements are always one step behind when adding or removing items.
I created a JSFiddle (using latest RC10 code), simply click the numbers to remove them from the Array: http://jsfiddle.net/hz6hcoog/
I've bisected and found the commit that caused this, it was the original rc8 commit, 6ba3576 .
Fiddle of 6ba3576 , where removing items doesn't work: http://jsfiddle.net/hz6hcoog/1/
Fiddle of 50dea23 (commit directly before 6ba3576 ), where adding/removing items works correctly: http://jsfiddle.net/hz6hcoog/2/
I have not yet taken a good look at the code to identify what causes this issue, so I can't yet make a pull request. I might be able to later, if I get a chance to look for a fix.
When scrolling in Firefox, there is a performance issue. When scrolling, the scroll amount is smaller then native scrolling.
It is present on demo page.
http://jsbin.com/jahikocopi/1/edit?js,console,output
The array is not expanding with new data - view
If I use {{::val}} and I expand the tbody, the data is not updated. Can this be somehow fixed? Because I think using one time data binding here should work.
<tbody vs-repeat2="28"
vs-excess="50"
vs-offset-after="{{ attrs.offset.bottom }}"
vs-scroll-parent="window">
<tr ng-repeat="row in attrs.data.tbody track by $index"
ng-class="row.theme">
<td ng-repeat="column in row.data track by $index"
ng-class="column.theme">
<div style="display: block" ng-style="{ width: attrs.styles[$index] }">
<span ng-repeat="val in column.data track by $index"
ng-class="column.themes[$index]">
{{::val}}
</span>
</div>
</td>
</tr>
</tbody>
When scrolling in Safari, there is a performance issue. When scrolling, depending on direction, there is a white background for a short time.
You can see it in the demo page.
Since vs-repeat keeps only necessary elements in DOM it is expected that value of $index will be different from the case of without vs-repeat.
See the jsbin example here
But I have a peculiar use-case where in the rendered table is sorted and/or filtered and I need to get $index value as shown in without vs-repeat example.
To give you details about use-case, the check-boxes in example can be multi-selected. i.e. I select a particular check-box hold Shift and then scroll down and check another check-box. Doing so should select all the check-boxes in between rows. Now for this to be implemented, I will want to know actual index values as in case of without vs-repeat.
Is there a workaround to get $index values similar to without vs-repeat? I tried to derive it using totalHeight and scrollTo values, but is there a more reliable way?
there seems to be a problem when the array in the ng-repeat expression is a child of another object, like this:
ng-repeat="item in parentObject.items"
created a gist based on the example that reproduces the problem:
https://gist.github.com/zippo445/ccf40271c19406e54135
nice piece of code BTW. If I can get over that little issue, it looks like a good solution for my current project!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.