How to identificate the li-item number inside angular-directive? - javascript

There is fiddle
var app = angular.module( 'myApp', [] );.....
I need to find out the number of list item , which is under editing or bluring to manipulate by it as I need.
How to do it ?

What about replacing this part of your jsFiddle:
<li ng-repeat="contact in contacts">
{{contact.name}}
</li>
with this:
<li ng-repeat="contact in contacts">
<edit-in-place value="contact.name"></edit-in-place>
</li>
That way you don't have to know the index of item as edit-in-place directive will take place after ng-repeat kicks in.
Priority of ng-repeat directive is 1000 and default directive priority (if you don't specify it) is 0.
More abourt directive's priorities from AngulaJS docs:
When there are multiple directives defined on a single DOM element,
sometimes it is necessary to specify the order in which the directives
are applied. The priority is used to sort the directives before their
compile functions get called. Priority is defined as a number.
Directives with greater numerical priority are compiled first.
Pre-link functions are also run in priority order, but post-link
functions are run in reverse order. The order of directives with the
same priority is undefined. The default priority is 0.
There is working jsFiddle.

Related

Getting DOM element in AngularJS directive

I´m trying to get a DOM element in order to change it inside a AngularJS1.0.6 directive.
HTML:
<li ng-repeat="car in cars" data-highlight="{{car.id}}">
Directive:
var iw = angular.element(document.querySelector('#iw-' + id));
console.log("iw=" + iw);
Please see the plunker for details: https://plnkr.co/edit/dP2cvut4f5ao5pFe6ka0?p=preview
After little research, I was able to make it work. Basically first issue comes when you use directive inside ng-repeat (also directive).
In this case directive's scope must be set for example like: scope: {car: '=highlight'}. This can desribe what happens. I would rather use <ul highlight="cars"></ul> along with directive's template like '<ul><li ng-repeat="car in cars"></li></ul>'. So ng-repeat would be inside directive.
When you get through, another issue comes in form of syncing two directives (different scopes). You need DOM ready to select element from another directive. I saved your compliled element to car object - it can be count as workaround that make it easier.
Forked plunker here
<li ng-repeat="car in cars track by $index" data-highlight="{{car.$index}}">
or
if whatever property exists, in your case, car must have id property

Why ng-show works with ng-repeat but ng-if doesn't? [duplicate]

This question already has answers here:
How to use ng-if with ng-repeat?
(5 answers)
Closed 7 years ago.
I have a simple ng-repeat that displays only half of the items. For some reason, i got it to work with ng-show but not with ng-if. I don't understand why?
this works:
<li ng-repeat="item in items" ng-show="$index < items.length / 2">{{item}}</li>
this doesn't:
<li ng-repeat="item in items" ng-if="$index < items.length / 2">{{item}}</li>
here is a jsfiddle to demonstrate:
http://jsfiddle.net/HB7LU/17269/
This question: AngularJS: ng-if not working in combination with ng-click? does not provide an answer why ng-show works while ng-if doesn't
I'm guessing this is because of the Angular's priority rendering cycle. They might've changed its behavior with newer versions as someone posted above.
In case like yours I usually make a custom filter for ngRepeat to slice the array and show only specified number of items based on the offset (ngRepeat pagination). I've never messed up with using ngRepeat directly with ngIf or ngShow/Hide as it can get really bugged whichever way you turn it.
ngRepeat directive creates and appends new node elements.
ngShow will allow angular to generate an element, but after that it will set it's display to none.
ngIf won't allow angular to generate an element.
As far as I know, ngIf has higher priority than ngRepeat, so I can assume that what's happening below the field is:
Angular sees the array.
ngIf doesn't know what $index (as it's part of ngRepeat) is so its cycle just runs by.
ngRepeat renders elements.
whilst ngShow works:
Angular sees the array.
ngRepeat renders elements.
ngShow shows them by specified condition.

AngularJS: ngTransclude and access scope of ngRepeat

We are in the process of upgrading our application to Angular 1.3.0. In doing so, we ran into a few issues, most of which seem to boil down to the behavior of ngTransclude inside of ngRepeat.
We have a directive that repeats a bunch of items, with a container around them, but does not own the children of that container. For instance, here is a simplified example:
<div ng-controller="myController">
There are {{items.length}} items.
<div my-directive items="items">
This item's name is {{item.name}}
</div>
</div>
Internally, the directive contains <li ng-repeat="item in items" ng-transclude></li>, among other things.
Prior to the update, this worked fine. The repeated, transcluded elements are in a scope that inherits from the scope created by ngRepeat. As of the update, the items are in a scope that inherits from the controller, and as far as I can tell, there is no way to access the scope created by ngRepeat.
Here are two JS Bin examples:
Old (1.3.0-beta.1) behavior: http://jsbin.com/kalutu/1/edit
New (1.3.0) behavior: http://jsbin.com/gufunu/1/edit
How can I achieve the old behavior, or some semblance of it, in Angular 1.3.0? If this is the intended behavior of ngTransclude, how can I repeat a bunch of child nodes without knowing what they are?
https://github.com/angular/angular.js/issues/8182
It was decided for 1.3 that ng-trasclude would not pull scope from the directive. There is a work-around on the linked pages,
https://github.com/angular/angular.js/issues/7874
https://github.com/angular/angular.js/issues/7874#issuecomment-47647528
This is the expected behavior.

Understanding the ngRepeat 'track by' expression

I'm having difficulties understanding how the track by expression of ng-repeat in angularjs works. The documentation is very scarce: http://docs.angularjs.org/api/ng/directive/ngRepeat
Can you explain what the difference between those two snippets of code is in terms of databinding and other relevant aspects?
with: track by $index
<!--names is an array-->
<div ng-repeat="(key, value) in names track by $index">
<input ng-model="value[key]">
</div>
without (same output)
<!--names is an array-->
<div ng-repeat="(key, value) in names">
<input ng-model="value[key]">
</div>
You can track by $index if your data source has duplicate identifiers
e.g.: $scope.dataSource: [{id:1,name:'one'}, {id:1,name:'one too'}, {id:2,name:'two'}]
You can't iterate this collection while using 'id' as identifier (duplicate id:1).
WON'T WORK:
<element ng-repeat="item.id as item.name for item in dataSource">
// something with item ...
</element>
but you can, if using track by $index:
<element ng-repeat="item in dataSource track by $index">
// something with item ...
</element>
a short summary:
track by is used in order to link your data with the DOM generation (and mainly re-generation) made by ng-repeat.
when you add track by you basically tell angular to generate a single DOM element per data object in the given collection
this could be useful when paging and filtering, or any case where objects are added or removed from ng-repeat list.
usually, without track by angular will link the DOM objects with the collection by injecting an expando property - $$hashKey - into your JavaScript objects, and will regenerate it (and re-associate a DOM object) with every change.
full explanation:
http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm
a more practical guide:
http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/
(track by is available in angular > 1.2 )
If you are working with objects track by the identifier(e.g. $index) instead of the whole object and you reload your data later, ngRepeat will not rebuild the DOM elements for items it has already rendered, even if the JavaScript objects in the collection have been substituted for new ones.

Angular.js: complex expression in limitTo filter inside ng-repeat

<li ng-repeat="chapter in book.chapters | limitTo:$parent.book.limit" >...</li>
this doesn't work but if i debug the scope of the li, $parent.book.limit has got a valid value (i've set it in the controller of course).
Isn't that code piece legit? Is there a way to achieve it?
The variable limit is on the parent because needs to be dynamically changed from other actions.
Plunk related: http://plnkr.co/edit/Hlz0nV
Remove $parent from $parent.book.limit and it should work.

Categories

Resources