data-binding not working on nested ng-repeat - javascript

When nesting ng-repeat it seems that clicking on the toggle button updates that addon in EVERY 'pair' (the first ng-repeat). Can anyone explain to me why this is the case and what I can do to fix it? Check the link above for the custom directive code...
<div ng-repeat="pair in pairs track by $index">
<h3>Pair {{ $index + 1}}</h3>
<div class='fieldrow'>
<button ng-repeat="addon in addons track by $index" toggle-button="addon.added">{{addon.name}} (£{{addon.price}})</button>
</div>
</div>

What is pair and what is addon, and how are they related. Right now, even though you have a nested ng-repeat, you have completely independent data structures, so addons array is same for each pair. Trott.
Based on this insight, I changed ng-repeat="addon in addons track by $index" to ng-repeat="addon in pair.addons track by $index"
Problem solved, thanks!

I think your code does not have any problem. see plunker here.
this code is working well:
<div ng-repeat="pair in pairs track by $index">
<h3>Pair {{ $index + 1}}</h3>
<div class='fieldrow'>
<button ng-repeat="addon in addons track by $index" toggle-button="addon.added">{{addon.name}} (£{{addon.price}})</button>
</div>
</div>

Related

If all array items are hidden show another div in AngularJS

I'm using ng-repeat on my page. ng-class working very well.
<div class="card news" ng-repeat="item in news track by $index" id="{{news.nid}}" ng-init="parentIndex = $index" ng-class="{hidden: '{{getCheck($index)}}' == 'true'}">
...
</div>
Now I need, if all items are hidden, show this div:
<h3 class="news-empty">No news</h3>
Whats the rules? How can I do it? Thanks.
You need another method that checks if all elements are hidden:
$scope.everythingIsHidden = function() {
return $scope.news.every((new, index) => $scope.getCheck(index));
}
$scope.getCheck = function(index) { // Your getChek function that I suppose it checks if an element is hidden based on index
//...
}
<h3 class="news-empty" ng-if="everythingIsHidden()">No news</h3>
TheCog's answer will work. If you want to do this in a more 'Angular' way you're going to need to refactor what you have.
You shouldn't be trying to hide them with a CSS class. ngRepeats have a built in filter syntax. So, you should be filtering them out.
<div class="card news"
ng-repeat="item in news | filterMethod as results track by $index"
id="{{news.nid}}"
ng-init="parentIndex = $index"
>
<h3 class="news-empty" ng-if="results.length === 0" >No news</h3>
The as results statement in the repeat will store the filtered array in results. filterMethodneeds to be an angular filter and it will probably work similarly to your getCheck($index) method.
You want to add an ngShow to the h3 tag, and aim it at a function you write in your controller that checks if the array is empty, probably by iterating over the same array that's hidden and running getCheck($index) on each.

track by $index isn't solving dupes error

I am trying to iterate through an array of objects and display them in my HTML using Angular. I have done this before without any problems by using "track by $index". But the standard error is still raised:
Error:
[ngRepeat:dupes] http://errors.angularjs.org/1.3.15/ngRepeat/dupes?p0=(key%2C%20value)%20in%20n&p1=string%3Ab&p2=b
But I have already added track by $index. I am confident there isn't any issue requesting the data as I have been able to display it correctly.
<div ng-repeat="n in post.userData.bookmarks track by $index" >
<div ng-repeat="(key, value) in n">
<div>{{ key }}</div>
</div>
</div>
Suggestions?
Dataset:
bookmarks: [{"1234": "Title1"}, {"5678": "Title2"}]
What happens is that a user bookmarks a post that they want to read later. I save the post id and the title of the post to an object and store this in an array. (I actually just wanted to store it to an object like so: {"1234": "Title1", "5678": "Title2"}, but couldn't figure it out with mongodb, since it doesn't seem to let you save as object data type.)
Then I want to ng-repeat the user's bookmarks in their profile. The only way I know how to do this is to iterate through the array and then iterate through each object. Of course, there is only one item in each object. But this is why I have the second ng-repeat. But when I do track by $index for both, as one of the answers lists below, it still doesn't give the desired behavior.
Something that could be causing a problem is that I also have a sort of dashboard that can be viewed on the side while viewing any given post. And on the dashboard they should be able to see their bookmarks. Also if they are on a post that they have bookmarked, if they click a (un)bookmark button on the post, it should automatically remove that bookmark on their bookmark dashboard.
But none of the suggestions have worked.
You forgot another ng-repeat: <div ng-repeat="(key, value) in n track by $index">
I don't know Why u write two times repeat
<div ng-repeat="n in post.userData.bookmarks track by $index" >
<a ng-href="/tuts/{{n.key}}">{{ n.key}}</a>
</div>
OR
<div ng-repeat="(key,value) in post.userData.bookmarks track by $index" >
<a ng-href="/tuts/{{value}}">{{ value}}</a>
</div>
key is anything which you get from object.

How to give continuous indexing for consecutive ng-repeat elements in angular

I am creating some div elements using multiple ng-repeat. Number of ng-repeat elements are dynamic.I want to give continuous indexing for all elements.How is it done in angular way?
like
<div ng-repeat="item in [1,2,1,5]">{{$index+1}}_{{item}}</div>
<div ng-repeat="item in [5,2]">{{$index+1}}_{{item}}</div>
<div ng-repeat="item in [4,6]">{{$index+1}}_{{item}}</div>
Expected result
<div>1_1</div>
<div>2_2</div>
<div>3_1</div>
<div>4_5</div>
<div>5_5</div>
<div>6_2</div>
<div>7_4</div>
<div>8_6</div>
This will work although it is dodgy. 'profile' is used to represent an object to avoid isolated scope. You can write the directive with this logic.
<span ng-init="profile.count = 0">{{profile.count}}</span>
<div ng-repeat="item in [1,2,1,5] track by $index"
ng-init="count=profile.count+1;profile.count=profile.count+1">{{::count}}_{{item}}</div>
<div ng-repeat="item in [5,2] track by $index"
ng-init="count=profile.count+1;profile.count=profile.count+1">{{::count}}_{{item}}</div>
<div ng-repeat="item in [4,6] track by $index"
ng-init="count=profile.count +1;profile.count=profile.count+1">{{::count}}_{{item}}</div>

Angular, limitTo and track by $index

I am trying to limit an object coming in by filtering (because there will be an option to show all eventually), however I am running into issues when trying to limitTo and track by index. Here is the code :
<div ng-repeat="item in filter.values track by $index | limitTo:filterLimit" class="cengage-builder-result-filter-value" value="item" update-filter="updateFilter">
In the controller:
$scope.filterLimit = 5;
It's saying I have dupes in the angular error so I'm thinking the track by $index isn't working here. Can't seem to find a proper way to do this, could use some help. Thanks!
Filters, like limitTo, orderBy, etc... must come before track by, since they apply to the array source, rather than to the track by expression.
<div ng-repeat="item in filter.values | limitTo:filterLimit track by $index">
Try this
Use limitTo
before track by
<div ng-repeat="item in filter.values | limitTo:filterLimit track by $index" class="cengage-builder-result-filter-value" value="item" update-filter="updateFilter">

AngularJS : nested ng-repeat peformance

I have a requirement where data is dynamic and very hierarchical (3- 4 level deep) where each inner level can be a list which can again contain list (please look at my template below). Everything looks good in terms of performance upto 2 ng-repeat but performance degrade sharply for level 3 onwards ng-repeat.
<div class="struct-property">
<div ng-repeat="structGroup in triple.properties track by $index">
<div ng-repeat="props in structGroup track by $index">
<simpleproperty triple="props"></simpleproperty>
<multiplevalueproperty triple="props"></multiplevalueproperty>
<div ng-if="props.isStructProperty">
<div class="struct-property">
......
<div ng-repeat="structGroupInner in props.properties track by $index">
<div ng-repeat="propsInner in structGroupInner track by $index ">
<simpleproperty triple="propsInner"></simpleproperty>
<multiplevalueproperty triple="propsInner"> </multiplevalueproperty>
</div>
</div>
</div>
</div>
Please Note: that I have only static data
I used "track by" but not sure if I used it correctly. I did tried to log if DOM is getting recreated with children ng-repeat and I do see that with every nested ng-repeat, parent DOM is getting regenerated and thats the reason performance is very bad.
I also tried to refactor my data so that I can avoid nested ng-repeat but unfortunately I cannot refactor it further because it as a RDF-JSON representation.
Thanks in advance!

Categories

Resources