exhtml
1/1/2018 - 12:54 PM

Angular ng-repeat


//array length
Items: {{ $ctrl.movies.length }}
//check length using ternary operators
{{ $ctrl.movies.length > 0 ? 'Something here' : 'Nothing here' }}

// ng-repeat $index property (usar con cuidado ya que por ejemplo si filtramos, 
// el $index no se corresponderia con el index real del array)
<li ng-repeat="movie in $ctrl.movies">
  {{ movie.title }} {{ $index }} Released: {{ movie.year }}


// ng-repeat without wrapper element via 'ng-repeat-start' / 'ng-repeat-end'
<dl ng-app="" ng-controller="DemoCtrl">
  <dt ng-repeat-start="definition in definitions" ng-bind="definition.title"></dt>
  <dd ng-repeat-end="" ng-bind="definition.text"></dd>

// you could also use a component/directive for that
<task-component ng-repeat="task in tasks" task="task"></task-component>

//*IMPROVING PERFORMANCE* via 'track-by'
//example: you have an ng-repeat with data, then you update the data in the controller
//this would cause ngRepeat to remove all li elements of existing tasks and create them again,
//which might be expensive if we have a lot of them or each li’s template is complex

//Behind the scenes ngRepeat adds a $$hashKey property to each task to keep track of it.
//If you replace the original tasks with new tasks objects from the server,
//even if those are in fact totally identical to your original tasks, they won’t have the $$hashKey property
//and so ngRepeat won’t know they represent the same elements.

//'track by' allows you to specify your own key for ngRepeat to identify objects by, instead of just generating unique IDs.
ng-repeat="task in tasks track by task.id" 
//since the ID would be the same in both your original tasks and the updated ones from the server,
//ngRepeat will know not to recreate the DOM elements and reuse them.

//example fiddle: http://jsfiddle.net/SeKk7/ (open console log to see the difference in rendering time)
//adding the track by, the task directive’s link function is no longer called on each refresh.



//order sobre ng-repeat
<a ng-click="reverse=!reverse;">Nombre</a> 
<tr ng-repeat="person in $ctrl.persons | filter:busqueda | orderBy:'nombre':reverse"></tr>
//en orderBy se pone como parámetro una propiedad (entre '') o un nombre de varialble
//para ordenar de manera inversa: orderBy:'-nombre'
//el ultimo parametro 'reverse' es optional: si 'true' reverses the order of the array.

//ordenar por varias propiedades (mediante una variable 'column' donde 
//almacenamosdinamicamente el criterio de ordenacion)
<th><a ng-click="column='nombre'; reverse=!reverse;">Nombre</a></th>
<th><a ng-click="column='sexo'; reverse=!reverse;">Sexo</a></th>
<tr ng-repeat="persona in $ctrl.listadoPersonas | filter:busqueda | orderBy:column:reverse">...</tr>

//search
//we create a local variable 'search' on the fly, 
//I don't need it to exist in the controller because 
//I don't want to keep track of her
<input type="text" placeholder="Search..." ng-model="search"/>
//we assign to the filter the value of search. 
//When the 'search' value changes in the model, Angular will start filtering
<li ng-repat="movie in movies.favorites | filter: search">...</li> 
//I can pass an object to a filter and tell it to search, 
//for example, only in the 'year' property. 
//Angular will run an 'object property lookup' on the movie
<li ng-repat="movie in movies.favorites | filter: { year: search }">...</li> 

//Dynamically change the key in the 'object lookup'
<a href="" ng-click="myKey='one';">Key one</a>
<a href="" ng-click="myKey='two';">Key two</a>
<p>{{ $ctrl.myObject[myKey] }}</p> //give me the value of key one or key two

//You can define an object with the properties you want to filter. 
//Then set the value of the properties dynamically with an input field:
Search by color: <input type="text" ng-model="search.colour" />
Search by title: <input type="text" ng-model="search.title" />
<div ng-repeat="product in $ctrl.products | filter:search" />

//You can also specify the property-value directly in the filter, 
//according with the data structure you are ng-repeating:
Search by color: <input type="text" ng-model="colorFilter" />
<div ng-repeat="product in $ctrl.products | filter:{ colour: colorFilter }">...</div>

//You can access deeper levels in the data hierarchy. 
//Example, to filter on thing.properties.title:
Search by title: <input type="text" ng-model="titleFilter" />
<div ng-repeat="thing in $ctrl.things | filter:{ properties:{ title: titleFilter } }">...</div>

//You can also filter on multiple properties of an object 
//just by adding them to your filter object:
<div ng-repeat="thing in $ctrl.things | filter:{ properties:{ colour: titleFilter, title: colorFilter } }">