Why does $parent.$index equals $index? - angularjs

In AngularJS 1.6.3 it is basically possible to nest ng-repeat.
I have determined, that in two nested ng-repeat the $parent.$index equals $index.
The following code is given:
<div ng-repeat="category in :: $ctrl.categories">
<span id="category-{{ $index }}">
{{ :: category.name }}
</span>
<ul>
<li ng-repeat="data in :: category.links"
id="link-{{ $parent.$index }}-{{ $index }}">
{{ :: data.name }}
</li>
</ul>
</div>
Expected resulting ID's for LI:
<div>
<span id="category-0">CatA</span>
<ul>
<li id="link-0-0">[..]</li>
<li id="link-0-1">[..]</li>
<li id="link-0-2">[..]</li>
</ul>
</div>
<div>
<span id="category-1">CatB</span>
<ul>
<li id="link-1-0">[..]</li>
<li id="link-1-1">[..]</li>
</ul>
</div>
Actual resulting ID's for LI:
<div>
<span id="category-0">CatA</span>
<ul>
<li id="link-0-0">[..]</li>
<li id="link-1-1">[..]</li>
<li id="link-2-2">[..]</li>
</ul>
</div>
<div>
<span id="category-1">CatB</span>
<ul>
<li id="link-0-0">[..]</li>
<li id="link-1-1">[..]</li>
</ul>
</div>
Can someone confirm this behaviour? Or did I miss something?

Working as expected.
angular.module('test', []).controller('Test', Test);
function Test($scope) {
var $ctrl = this;
$ctrl.categories = [
{
name: 'cat1',
links: [{name: 'l1'}, {name: 'l2'}, {name: 'l3'}]
},
{
name: 'cat2',
links: [{name: 'l4'}, {name: 'l5'}]
}
]
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<div ng-app='test' ng-controller='Test as $ctrl'>
<div ng-repeat="category in :: $ctrl.categories">
<span id="category-{{ $index }}">
{{ :: category.name }}
</span>
<ul>
<li ng-repeat="data in :: category.links"
id="link-{{ $parent.$index }}-{{ $index }}">
{{ :: data.name }}
</li>
</ul>
</div>
</div>
You probably have some scope generating elements surrounding your child layer e.g. ng-if, ng-repeat, ng-switch. In this case you'll need to add more layers of $parent

Related

AngularJS- how to change value of dynamic model

I want to change {{order.status}} to def when someone click updatestatus button.
<ul>
<li ng-repeat="order in orders">
<!--
<div ng-model="row[order.id]" >abc</div>
-->
<div ng-model="row[order.id]" >{{order.status}}</div>
updatestatus
</li>
</ul>
Controller
$scope.row = {};
$scope.changestatus = function(id) {
//console.log(id);
$scope.row[id] = 'def';
}
It does not work. Please help.
You don't need ng-model here. ng-model is used for inputs, textarea, select or custom form elements https://docs.angularjs.org/api/ng/directive/ngModel
<ul>
<li ng-repeat="order in orders">
<div>{{ row[order.id] }}</div>
updatestatus
</li>
</ul>
Here, you just need to update the view. For this ng-bind is used https://docs.angularjs.org/api/ng/directive/ngBind
<div> ng-bind="row[order.id]"></div> and <div>{{ row[order.id] }}</div> are similar
UPDATE
<ul>
<li ng-repeat="order in orders">
<div>{{ order.status }}</div>
Update Status
</li>
</ul>
Controller:
$scope.changestatus = function(order) {
//console.log(order.id);
order.status = 'the update status'; // status changed
}
Use {{row[order.id]}} instead of abc in your view and remove ng-model within your div.
<ul>
<li ng-repeat="order in orders">
<div>{{ row[order.id] }}</div>
updatestatus
</li>
</ul>
Or
<ul>
<li ng-repeat="order in orders">
<div ng-bind="row[order.id]"></div>
updatestatus
</li>
</ul>

AngularJS performance issue ng-model vs ng-class etc

I have a list with ng-repeat in angular and a button which toggle checked property in all items (1.4):
<button ng-click="selectAll()">select all</button>
example 1:
<li ng-repeat="item in items">
<input type="checkbox" ng-model="item.checked"> {{ item.name }}
</li>
example 2:
<li ng-repeat="item in items">
<span class="glyphicon" ng-class="{'glyphicon-ok': item.checked}"></span> {{ item.name }}
</li>
example 3:
<li ng-repeat="item in items">
<span class="glyphicon glyphicon-ok" ng-show="item.checked"></span> {{ item.name }}
</li>
example 4:
<li ng-repeat="item in items">
<span>{{ item.checked }}</span> {{ item.name }}
</li>
Performance of example 1 and 4 is OK. But example 2 and 3 has almost 1 sec. lag. There about 200 items in the array.
Why the performance is so different? I would like to have custom "checkboxes" with glyphicon - so I would like to have example 2 work but the performance is bad
You can try the following for example 2:
<li ng-repeat="item in items track by item.checked">
<span class="glyphicon" ng-class="{'glyphicon-ok': item.checked}"></span>
{{ item.name }}
</li>
For example 3, try this:
<li ng-repeat="item in items track by item.checked">
<span class="glyphicon glyphicon-ok" ng-if="item.checked"></span> {{ item.name }}
</li>

angularjs how to increment init variable value in ng-repeat without onclick?

How to increment init variable value in ng-repeat
<div ng-if="feedData.carouselMode == true" ng-init='start=0' ng-repeat="a in carousel_data">
<div class="owl-demo" class="owl-carousel" owl-carousel >
<div class="item" ng-repeat="(key, item) in a.carouselFeeds" ng-init="start=start+1">
{{start}}
<div ng-click="go('{{key}}', item.feedUrls.length, 'rtl')" ng-swipe-left="go('{{key}}', item.feedUrls.length, 'rtl')">
<img class="lazyOwl" ng-src="{{item.img}}" />
<span class="innersquare" image-ja="{{item.img}}">
<p ng-style="folderStyle">{{item.name }} </p> </span>
</div>
</div>
</div>
</div>
ng-init start=0 after increment start=start+1 in ng-repeat but no count only show 1.
This is because each ng-repeat has its own scope and each ng-init will just increase its own scoped variable. You can try access the parent scope with $parent.
In case you are looking for a continuous numeration try this
<div ng-controller="MyCtrl">
<div ng-repeat="a in ['a','b','c']" ng-init="current = $parent.start; $parent.start=$parent.start+3;">
<div ng-repeat="x in ['alpha','beta','gamma']">
{{current + $index}}
</div>
</div>
Where the +3 should be +[LENGTH OF INNER ARRAY].
http://jsfiddle.net/rvgvs2jt/2/
For your specific code it would look like this
<div ng-if="feedData.carouselMode == true" ng-init='current=$parent.start; $parent.start=$parent.start+a.carouselFeeds.length' ng-repeat="a in carousel_data">
<div class="owl-demo" class="owl-carousel" owl-carousel>
<div class="item" ng-repeat="(key, item) in a.carouselFeeds">
{{current + $index}}
<div ng-click="go('{{key}}', item.feedUrls.length, 'rtl')" ng-swipe-left="go('{{key}}', item.feedUrls.length, 'rtl')">
<img class="lazyOwl" ng-src="{{item.img}}" />
<span class="innersquare" image-ja="{{item.img}}">
<p ng-style="folderStyle">{{item.name }} </p> </span>
</div>
</div>
</div>
</div>
I guess you achieve this by simple {{$parent.$index}}
Update
As per comments
<div ng-controller="MyCtrl">
<div ng-repeat="a in one">
<div ng-repeat="x in two">
{{($parent.$index*two.length)+($index+1)}}
</div>
</div>
Controller:-
$scope.one= ['alpha','beta','gamma'] ;
$scope.two=['alpha','beta','gamma'];
Fiddle
You can be accessed with $index, check this code,
<div ng-app ng-controller="TestController">
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item.value" type="text"/>
</div>
{{list}}
</div>
and
function TestController($scope) {
$scope.list = [ { value: 'value 1' }, { value: 'value 2' }, { value: 'value 3' } ];
}
AngularJS is giving $index variable. We can use it.
<ul>
<li ng-repeat="item in items">{{ $index + 1 }}</li>
</ul>

how i get total of item in ng-repeat

I'm trying to get the overall number of items in each iteration.my code is this
<ul class="phones">
<li ng-repeat="phone in phones | filter:query | orderBy:orderProp"
ng-init="index()" class="thumbnail">
<a href="#/phones/{{phone.id}}" class="thumb">
<img ng-src="{{phone.imageUrl}}">
</a>
{{phone.name}}
<p>{{phone.snippet}}</p>
</li>
</ul>
<div>
{{ total }}
</div>
Controller
phonecatApp.controller('PhoneListCtrl', function($scope, $http)
{
$scope.total =0;
$scope.index =function()
{
$scope.total ++;
}
}
By dynamic you mean total no of phones currently displayed after filter is applied.
<ul class="phones">
<li ng-repeat="phone in filtered = (phones | filter:query | orderBy:orderProp)"
ng-init="index()" class="thumbnail">
<a href="#/phones/{{phone.id}}" class="thumb">
<img ng-src="{{phone.imageUrl}}">
</a>
{{phone.name}}
<p>{{phone.snippet}}</p>
</li>
</ul>
<div>
{{ filtered.length }}
</div>
To make more sense of data (Bonus Tip :) )
<div ng-show="query">
<ng-pluralize count="filtered.length" when="{'0': ' No search result ', 'one': ' 1 search result ', 'other': ' {} search results '}"></ng-pluralize> for {{query}}
</div>
Are you trying to get total number of phones?
you can simply use length property in expression instead {{ total }}
{{ phones.length }}

why ng-repeat stop working at level 3

I am using angularjs to render a hierarchical structure. The test case is at http://jsbin.com/agodoj/1/edit
My question is why ng-repeat stop working at level 3 ? Thanks
Here is my model
function Test($scope) {
$scope.cars = {
chrylser: {
nameplates: [{
name: "np1",
trims: [
"tirm1", "trim2"
]
}]
}
};
}
Here is my template
<div ng-app ng-controller="Test">
<div ng-repeat="(key, value) in cars">
{{key}}
<ul>
<li ng-repeat="np in value.nameplates">{{np.name}}, {{np.trims}}</li>
<ul>
<li ng-repeat="trim in np.trims">
(ng-repeat stop working here) {{trim}}
</li>
</ul>
</ul>
</div>
</div>
Just need to move the closing </li> tag after your inner <ul>. You had the <li ng-repeat="np in value.nameplates"> immediately closing, ending the loop.
<div ng-app ng-controller="Test">
<div ng-repeat="(key, value) in cars">
{{key}}
<ul>
<li ng-repeat="np in value.nameplates">{{np.name}}, {{np.trims}}
<ul>
<li ng-repeat="trim in np.trims">
works! {{trim}}
</li>
</ul>
</li>
</ul>
</div>
</div>

Resources