generate unique element IDs in nested ng repeat - javascript

I am facing problems generating unique IDs for nested ng-repeat blocks in angularJS. Also, I need to manage a common ngModel for all radio buttons with unique ngValues.
The basic layout is as follows:
<div ng-repeat="folder in folders">
<div ng-repeat="files in folder">
----------
----------
----------
</div>
<div ng-repeat="folder in folder.childFolders">
<div ng-repeat="files in folder">
----------
<input type="radio" ngModel="" ngValue="">
----------
</div>
-----------
<<This block can further nest to many levels>>
-----------
</div>
</div>
Hence, using $parent or $index is not an option here. Similarly, using radio buttons is also creating problem inside the nested block as ngModel requires a value which is common to all scopes and ngValue also needs to be unique for all radio buttons.
Thanks in anticipation

Related

Is it possible to make a Web Component List with undetermined number of slot?

I know it can be achieved using Javascript by manually separate the slot elements and put them into the DOM tree but I wonder if it's supported within the box. Something like this:
<my-element>
<div slot="items">Item 1</div>
<div slot="items">Item 2</div>
<div slot="items">...</div>
</my-element>
And the template should be like this:
<div class="items">
<div class="item"> <!-- Should be 1 item per slot -->
<p>Something else</p>
<slot name="items"></slot>
</div>
</div>
Is this only possible using slotchange and populate the items by Javascript? Is there any better solution, without Javascript or with less Javascript? Maybe there is an element similar to slot that I am not aware of?
since all slot="items" will be slotted into <slot name="items"> only with the slotchange Event can the Component Author determine what happened.
Note: You do not populate the items, the default slotting mechanism does; you can only remove items after they are slotted; but then your HTML above needs more info on which Item needs to be slotted.
Then the question remains, Why use multiple slot="items" at all then?? If a slot can take 1 item, then only assign 1 item
Imperative Slots might help out: https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Imperative-Shadow-DOM-Distribution-API.md
Update, I misunderdstood OPs question
All he needs to do is:
Create another Web Component: <slotted-item slot="items"></slotted-item>

ng-repeat item reference is showing up differently in angular ui router link

I have a ng-repeat for an array of message objects, which prints out message.text and is accompanied by message.author.username. When I use {{message.author.username}}, it prints out the correct user, but I have that DOM element wrapped in an anchor, where ui_sref=profile(message.author.username) is set as the link.
For some reason the ui-sref link's reference to the username is presenting something totally different than what it's wrapped around. Like, when I hover over the linked username on the site, it shows that the link goes to a different username found later in the array. If it's using the same exact syntax (message.author.username) is there any reason for the text to be different when listed in an ui-router anchor tag? I feel like it's a bug but I'm not sure why and how to fix.
Hopefully that made sense... here's some code to be clear
<div class="col-sm-9 offset-sm-1"
ng-repeat="message in wall | orderBy: createdon:true | limitTo: 8">
<div class="comment-container">
<div >
<h6> <a ui-sref="profile(message.author.username)">{{message.author.username}}</a></h6>
</div>
<div class="comment-text">
{{message.text}}
</div>
<hr>
</div>
</div>

How can I isolate/encapsulate $index in Angular using 2 ng-repeat directives on the same page?

I have a website built with Angular 1.4 with 2 slideshows. One in the header and one for a partner logo slider. They are in the same view when all it said and done.
Header
<div layout="row">
<div flex="100" flex-gt-sm="70" hide-xs class="header-slider center">
<img
ng-repeat="i in slides"
class="header-slide-animation"
src="{{i.img}}"
ng-hide="!isCurrentSlideIndex($index)"
ng-class="{'active':isCurrentSlideIndex($index)}"/>
</div>
And then here's the logo slider
<div class="partners-slider center">
<a ng-repeat="i in slides"
class="slide-animation"
href="{{i.href}}"
target="_blank"
ng-hide="!isCurrentSlideIndex($index)"
ng-class="{'active':isCurrentSlideIndex($index)}">
<img src="{{i.img}}" alt="{{i.title}}" />
</a>
I'm following this tutorial here http://onehungrymind.com/build-sweet-photo-slider-angularjs-animate/ and it uses TweenMax animate the sides.
Everything was working great with one slide show on the page but I have each split into separate directives being included on the same page and the problem is that $index is conflicting. The partner logo animation moves faster than the header slide show and also has a larger array so you can imagine the problem when the header's $index gets overwritten by the other and is out of range, etc... What can I do to isolate $index so the two slideshows don't step on each other?
It's not $index that is the problem, it is the shared scope whereby each directive is sharing the parent controller scope.
$index is actually isolated as it only exists in each child scope of ng-repeat
So whatever isCurrentSlideIndex($index) is doing in controller will be shared by both instances
The simple solution is to use an isolated scope in directive so both are separate instances.
Just move the methods used in controller to directive. You can then use one attribute in directive to receive the images in the isolated scope from the parent controller
Alright I found an article that helped me realize a solution to the problem. http://codeutopia.net/blog/2014/11/10/angularjs-best-practices-avoid-using-ng-repeats-index/
Overall the moral of the story is not to use $index because it can be problematic. I chose to modify the view to pass the image object and check for that against the current index.
HTML
<div layout="row">
<div flex="100" flex-gt-sm="70" hide-xs class="header-slider center">
<img
ng-repeat="j in headerSlides"
class="header-slide-animation"
src="{{j.img}}"
ng-hide="!isCurrentHeaderSlide(j)"
ng-class="{'active':isCurrentHeaderSlide(j)}"/>
</div>
This is what the JavaScript was
$scope.isCurrentSlideIndex = function (image) {
return $scope.currentIndex === index;
};
This is what I changed it to
$scope.isCurrentHeaderSlide = function (slide) {
return $scope.headerSlides[$scope.currentIndex] == slide;
};
And it works :-)

Updating the limitTo value on a specific nested ngRepeat

I'm new to AngularJS and having to work on an app that has a section of nested ngRepeats such as this below.
<div class="title-bar" ng-repeat="orderType in someObj.orderTypes">
<div class="inner-panel" ng-repeat="status in orderType.statuses">
<p>{{status.Name}}</p>
<div class="order-list" ng-repeat="order in status.Orders | limitTo:orderFilterLimit">
<p>{{order.Stuff}}</p>
</div>
<button ng-show="(status.Orders.length > orderFilterLimit)" ng-click="loadMoreOrdersToList()">Load More</button>
</div>
</div>
The status.Orders list can be quite large at times so I limit it. When a user wants to view more data for that specific section (which is enumerated by status) I add 3 to the orderFilterLimit. The problem is when I do this it is adding 3 to every single .order-list in the .inner-pannel element. Is there a way I can change the orderFilerLimit variable based on an id or class of the element it's attached to?
For context here is a super simple snippet of what loadMoreOrdersToList() is doing.
https://jsbin.com/vapucixesa/1/edit?js
No need of declare the orderFilterLimit inside controller, You should have scope variable inside ng-repeat itself so that it ng-repeat element will have separate copy of orderFilterLimit because ng-repeat create a child scope on each iteration.
Markup
<div class="title-bar" ng-repeat="orderType in someObj.orderTypes" ng-init="orderFilterLimit = 3">
<div class="inner-panel" ng-repeat="status in orderType.statuses">
<p>{{status.Name}}</p>
<div class="order-list" ng-repeat="order in status.Orders | limitTo:orderFilterLimit">
<p>{{order.Stuff}}</p>
</div>
<button ng-show="(status.Orders.length > orderFilterLimit)" ng-click="orderFilterLimit = orderFilterLimit + 3">Load More</button>
</div>
</div>

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