Angular: one-time binding, recompiling of nested ng-repeat - javascript

I am using one-time binding and kcd-recompile, but have a problem with nested ng-repeat. Let's assume the code looks like this:
<div ng-repeat="person in ::people">
<div ng-repeat="friend in ::person.friends" kcd-recompile="person.friends">
{{friend.name}}
</div>
</div>
If I add a friend to one of the people now, I want this person div to be recompiled without recompiling the other people's divs. The problem is: person.friends is only updated, if person is updated.
So it works if I add the kcd-recompile to the first ng-repeat, but then every person's div is recompiled (which I want to prevent).
Is there any possibility to update person without recompiling the whole first ng-repeat?

Found a solution on my own (after hours), if anyone needs it:
Using people[$index].friends instead of person.friends, it works!
<div ng-repeat="person in ::people">
<div ng-repeat="friend in people[$index].friends" kcd-recompile="person.friends">
{{friend.name}}
</div>
</div>

Related

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>

Angular 1.4: How do I force update of directive within a ng-repeat with filter?

How does one force a directive to update if it nested in a ng-repeat which has a filter?
Input Box
<input type="text" class="name-search" ng-model="search.text">
HTML
<ul>
<li ng-repeat="user in users track by $index | filter:search">
<profile-photo user="user"></profile-photo>
<span>{{ user.name }}</span>
<li>
</ul>
As I type in the input box, the users filter properly but the profile-photo directive doesnt have the proper user.
Any help would be greatly appreciated!
Heres a dumbed down Plunker of my actual code. If you start typing, you will notice that it filters but the image doesnt update.
https://plnkr.co/edit/FWD2bFdIh7jQa5aqdkjrPlunker
your link's function code only executes once, when compiling the directive. After that, scope.photoUrl does not change even if you change the user, because you're not $watching the value. You can add a watch, or directly, use this in the template
ng-src="{{user.photoUrl}}"

How can I use *ngFor current object outside of the ngFor?

The title might seem weird but what im talking about is basically what this link is doing.
Im look for a way to use the current iterated person in a <tr> outside of the *ngFor scope.
In the link he used ng-repeat-start and ng-repeat-end to include multiple tag withing the ng-repeat. How can i achieve the same behavior withing Angular2 using *ngFor?
I had to use the <template> tag, which made the iterated objected accessible within it.
<ng-template let-person ngFor [ngForOf]="people">
<tr>
<td>{{person.name}}</td>
<td>{{person.gender}}</td>
</tr>
<div>
<span>{{person.details}}</span>
</div>
</ng-template>
Hope it'll help somebody
The * in *ngFor (and really any angular directive) is shorthand that tells angular to surround the element in an ng-template, which is just the angular implementation of . You can read about how that happens at https://angular.io/guide/structural-directives, but I'll reproduce the relevant example below.
If your code contains
<div *ngIf='object'>{{object.property}}</div>
as part of the render process, angular transposes that to
<ng-template [ngIf]='object'>
<div>{{object.property}}</div>
</ng-template>

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!

In AngularJS how can I create a new ngController dynamically?

I'm trying to create new ngControllers on the fly, is this possible? I'm not writing it into the template with a ngRepeat or anything, since the user might never create an instance of a certain ngController.
Here's an example of my current template:
<div ng-controller="ViewUsers">
<div class="viewUsersList">
<table>
<tr class="userRow" ng-click="viewUser(user.user_id)" ng-repeat="user in users">
<td>{{user.first_name}} {{user.last_name}}
<br />{{user.phone}}
</td>
</tr>
</table>
</div>
</div>
So far it works great. When the user clicks a .userRow it calls viewUser(ID). The problem is here:
I want to create a new block of code like this:
<div ng-controller="UserDetail">
{{first_name}}
</div>
And append this to the DOM.
So if they click on Bobby and Sally, two UserDetail controller objects would be added to the DOM and work accordingly. (Ideally, I'd like to pass in the data-bound user model, but that's for later).
I tried a ghetto version in JSBin, but I'd rather not use JQuery if possible:
http://jsbin.com/EdOteTav/2/edit
Can anyone shine some light on this? Thanks in advance
I would change the code little bit and use directive instead of controller. See this simple and quick example in jsfiddle.
The directive would handle the click events and display whatever you want to display on the DOM. You can get the full user object from scope.user inside the directive.

Categories

Resources