I have webpage that has paging for an outer loop of elements, that when clicked will expand, make a call to the server, then display another table filled with paginated rows. I only experience this hang in IE which I have come to find seems like a common problem.
The outer results set will only display 25 rows at a time. The inner will also only display 25 rows at a time. Only one accordian panel can be opened at a time. I am using track by and one time bindings. The repeat-starts both have corresponding repeat-ends. The outer result set loads very quickly with no hangs.
I am using angularjs 1.5.8.
Some sample snippets of html:
<div class="accordionHdr" ng-repeat-start="(index, obj1) in ::vm.obj1Array track by $index">
//normal accordian panel stuff here. clicking a panel calls server to get inner results
//normal table code
<tr ng-repeat-start="(index2, obj2) in ::vm.obj2Array track by $index">
<td>several cells in here</td>
</tr>
</div>
What can I do to eliminate this hang that only exist in IE? Thanks in advance
Related
HTML:
{{vm.regions}}
<div ng-repeat="region in vm.regions">
{{region}}
</div>
On button presses, the model a.k.a vm.regions gets updated in the controller. For example vm.regions = [].
I can see that the array {{vm.regions}} is instantly updated, but the elements in the div take at least a second to update, meaning you can see old elements for a bit in the newly updated list, for example.
What is causing this?
It is in AngularJs Best Practices to always add "track by $index" in order to inprove performances.
{{vm.regions}}
<div ng-repeat="region in vm.regions track by $index">
{{region}}
</div>
Link : https://docs.angularjs.org/api/ng/directive/ngRepeat
Try using vs-repeat. It applies virtual scrolling to ng-repeat which increases its performance drastically even if you are not using one time binding.
http://kamilkp.github.io/angular-vs-repeat/#?tab=8
I have a request that I'm scratching my head over, and I'm hoping someone can help me out. The client is looking for a sidebar widget that would display related items of a product. To conserve on vertical space, I have made this area collapsable using a Bootstrap accordion.
After reviewing what I developed, they like the idea but they wish to take it a step farther. The client would like the first three related items always displayed in this related items area, BUT if the items exceed 3, then add the collapsible element below with a toggle button (SHOW MORE). Problem is, I'm stuck on how the logic would play out in JSTL.
JSTL:
<ul>
<c:set var="count" value="0" scope="page" />
<c:forEach var="itemID" items="${sellableGood.relatediItem}">
<c:set var="count" value="${count + 1}" scope="page" />
<script>console.log(${count});</script>
<li>
${itemID}
</li>
</c:forEach>
</ul>
Here's what I have currently, it's a basic forEach loop that just iterates through all of the related items. I'm puzzled on how I would use the COUNT variable to know when there was more than 3, then put those in a div within this unordered list. Or is there a way to get the total count before I start outputting the unordered list in the first place?
Thank you in advance.
The following snippet should help to check if count is greater than 3
<c:if test="${count > 3}">
your logic
</c:if>
I use ng-repeat to populate my table. One of the columns in the table should be dynamically populated again by a different function call.
Below is my code snippet.
<tr ng-repeat="item in ctrl.items">
<td><span ng-bind="item.name"></span></td>
<td><span ng-bind="getItemDetails(item.id)"></span></td>
</tr>
I have array of items. I need to display those items in a table. Item name will be present in the item object, however, item details will be populated by another function call which needs item id.
On using ng-bind (like in the code above) I face 2 issues.
Multiple calls to function even if array has 1 items. Sometimes it goes on thereby freezing my browser and server out of memory issue
The item id doesn't get passed to function always. Sometimes it is undefined.
I am not sure if ng-bind is the right directive to be used. ng-model doesn't work though. Is there any other directive or other way to do it?
How can I achieve this?
EDIT:
Here is the jsfiddle url: https://jsfiddle.net/grubxaur/
If you check browser console, you can see the function is called twice. I guess it is called N no. of times where N is no. of columns in the table.
I have tweaked my implementation a bit to get rid of this issue. Rather than calling a function within ng-repeat, I modified the items array within the controller using angular.forEach before ng-repeat is invoked.
Something like code below.
angular.forEach(self.items, function(item){
item.details = $scope.getItemDetails(item.id);
});
I am trying to make a nice display of my array data within an element that has a certain width/height. What I want to do is that when my data reaches the bottom of the element to start a new column and continue with printing the data within that next column and so on/forth
Any help is much appreciated!
My code:
<div class="repeater" ng-repeat="files in files"> {{files.name}}
<div class='progress-bar'>
<div class='percentage' ng-style="style">
</div>
</div>
</div>
Current view:
HTML/CSS solution
This should be better solved by CSS than by your application logic. You could display the file names as list and adapt the approach at
How to display an unordered list in two columns?
to display them in multiple columns.
I'm rendering a calendar UI with AngularJS and I'm running into some pretty big performance issues when flipping through the weeks. Let me explain.
The UI looks something like this:
I loop over all the persons, then for each person I loop over the days, and then render the calendar objects for that user for that day. Something like this (simplified):
<div ng-repeat="user in ::ctrl.users track by user.id" class="row">
<div ng-repeat="day in ctrl.days" class="cell">
<div ng-repeat="item in ctrl.items[user.id][day] track by item.id">
<div class="item">
There are not a crazy amount of watcher on this page (about 500), almost everything is bind-once.
The problem is when the user clicks the prev/next buttons to load the previous or next week. This changes the ctrl.days array with new days, and all the correct items are loaded. This performs fine until you have a ton of people and calendar items. Then all the destroying and recreating of DOM elements is really slow.
I came across the sly-repeat directive which is meant to cache and reuse DOM elements but because my outer ng-repeat changes (ctrl.days), the inner ng-repeat (with the items) is also recreated. So it doesn't really work.
How can I solve this problem? Right now browsing through the weeks with a large data-set takes about 2 seconds, which is of course not acceptable. With a small set of users and calendar items everything is super snappy.
Try using track by in your nested ng-repeats. This will prevent them from reloading unnecessary inner repeats. For more information, see:
http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/