I have the following:
<li ng-repeat="category in categories" ng-if="category.id== '3'">
<div ng-repeat="item in items" ng-if="item.no == category.no" ng-style="{'margin-left': ($first ? '20px': '0px')}">
...
</div>
</li>
it can only work on the very first item, but not every first item in each li. How can I update this?
You need to try it like this. The way you were doing it $first refers to the first ng-repeat.
<li ng-repeat="category in categories" ng-if="category.id== '3'">
<div ng-repeat="item in items" ng-if="item.no == category.no">
// use $parent.$first to check for the first item of categories
// using $first here refers to first item in items array
<div ng-style="{'margin-left': ($first ? '20px': '0px')}">...</div>
</div>
</li>
The below code renders tabs, sections under each tab and the content of the section. When navigating from one section to another, I notice the number of watchers are increasing (or) adding up each time.
Can any one tell what could be the reason for this. Appreciate any pointers
<ul class="nav nav-tabs">
<li ng-repeat="tab in tabList track by tab.tabId" id="{{tab.attribute}}"
ng-class="{active:selectedTab.attribute === '{{tab.attribute}}'}">
<a showtab="" href="#{{tab.attribute}}" ng-click="setSelectedTab(tab)">{{tab.displayLabel}}</a>
</li>
</ul>
<div class="tab-pane">
<div class="" ng-if="selectedTab.sectionList.length > 0">
<ul class="nav nav-pills pills-section">
<li ng-repeat="section in selectedTab.sectionList track by section.sectionId" id="{{section.attribute}}" ng-class="{active:selectedSection.attribute === '{{section.attribute}}'}">
<a showtab="" href="#{{section.attribute}}" ng-click="setSelectedSection(section)">{{section.displayLabel}}</a>
</li>
</ul>
<!-- Content of the section rendered with ng-repeat -->
<div ng-include="sectionContent"/>
</div>
</div>
The section content has the below mark up
<table>
<tbody>
<tr ng-repeat="field in selectedSection.fields track by field.fieldId">
</tr>
</tbody>
</table>
I have had similar problems before, nesting ng-repeats is never a good idea, but we are forced from time to time to do it. This is your solution to have performance benefits.
http://kamilkp.github.io/angular-vs-repeat/
I need the following:
<ul>
<li data-ng-repeat="person in row1">
<img data-ng-src="img/{{person.code}}.jpg">
<h3>{{person.name}}</h3>
<p>{{person.description}}</p>
</li>
</ul>
<ul>
<li data-ng-repeat="person in row2">
<img data-ng-src="img/{{person.code}}.jpg">
<h3>{{person.name}}</h3>
<p>{{person.description}}</p>
</li>
</ul>
but I don't want to duplicate the html - I want to be able to pass in the two different arrays (row1 and row2) to ng-include or something similar. How can I do this in AngularJS?
You can give the array of rows to another model and use ng-repeat in ul tag
In your controller:
$scope.rows = [row1, row2];
In your template:
<ul ng-repeat="row in rows">
<li ng-repeat="person in row">
<img data-ng-src="img/{{person.code}}.jpg">
<h3>{{person.name}}</h3>
<p>{{person.description}}</p>
</li>
</ul>
I'm building a twitter bootstrap list using angular's ng-repeat:
<ul class="dropdown dropdown-menu">
<li class="menuOption" ng-repeat="option in options">
<a data-ng-click="option.value>0 ? foo() : goo()">
{{option.label}}
</a>
</li>
</ul>
Now, I want to include a divider (<li class="divider"></li>) inside this list. It should be before the last element in the list (which is also indicated by option.value with a negative value, which is probably an easier indication).
My problem is that since the ng-repeat iteration is on the li element itself, I couldn't find a way to use ng-if on this element.
Try ng-repeat-start and ng-repeat-end:
<ul class="dropdown dropdown-menu">
<li class="menuOption" ng-repeat-start="option in options" ng-if="option.value>0">
<a data-ng-click="option.value>0 ? foo() : goo()">
{{option.value}}
</a>
</li>
<li class="divider" ng-repeat-end ng-if="option.value<0">
option < 0 ({{option.value}})
</li>
</ul>
DEMO
So I have an ng-repeat nested within another ng-repeat in order to build a nav menu. On each <li> on the inner ng-repeat loop I set an ng-click which calls the relevant controller for that menu item by passing in the $index to let the app know which one we need. However I need to also pass in the $index from the outer ng-repeat so the app knows which section we are in as well as which tutorial.
<ul ng-repeat="section in sections">
<li class="section_title {{section.active}}" >
{{section.name}}
</li>
<ul>
<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu($index)" ng-repeat="tutorial in section.tutorials">
{{tutorial.name}}
</li>
</ul>
</ul>
here's a Plunker http://plnkr.co/edit/bJUhI9oGEQIql9tahIJN?p=preview
Each ng-repeat creates a child scope with the passed data, and also adds an additional $index variable in that scope.
So what you need to do is reach up to the parent scope, and use that $index.
See http://plnkr.co/edit/FvVhirpoOF8TYnIVygE6?p=preview
<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu($parent.$index)" ng-repeat="tutorial in section.tutorials">
{{tutorial.name}}
</li>
Way more elegant solution than $parent.$index is using ng-init:
<ul ng-repeat="section in sections" ng-init="sectionIndex = $index">
<li class="section_title {{section.active}}" >
{{section.name}}
</li>
<ul>
<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu(sectionIndex)" ng-repeat="tutorial in section.tutorials">
{{tutorial.name}}
</li>
</ul>
</ul>
Plunker: http://plnkr.co/edit/knwGEnOsAWLhLieKVItS?p=info
What about using this syntax (take a look in this plunker). I just discovered this and it's pretty awesome.
ng-repeat="(key,value) in data"
Example:
<div ng-repeat="(indexX,object) in data">
<div ng-repeat="(indexY,value) in object">
{{indexX}} - {{indexY}} - {{value}}
</div>
</div>
With this syntax you can give your own name to $index and differentiate the two indexes.
Just to help someone who get here... You should not use $parent.$index as it's not really safe. If you add an ng-if inside the loop, you get the $index messed!
Right way
<table>
<tr ng-repeat="row in rows track by $index" ng-init="rowIndex = $index">
<td ng-repeat="column in columns track by $index" ng-init="columnIndex = $index">
<b ng-if="rowIndex == columnIndex">[{{rowIndex}} - {{columnIndex}}]</b>
<small ng-if="rowIndex != columnIndex">[{{rowIndex}} - {{columnIndex}}]</small>
</td>
</tr>
</table>
Check: plnkr.co/52oIhLfeXXI9ZAynTuAJ
Just use ng-repeat="(sectionIndex, section) in sections"
and that will be useable on the next level ng-repeat down.
<ul ng-repeat="(sectionIndex, section) in sections">
<li class="section_title {{section.active}}" >
{{section.name}}
</li>
<ul>
<li ng-repeat="tutorial in section.tutorials">
{{tutorial.name}}, Your section index is {{sectionIndex}}
</li>
</ul>
</ul>
When you are dealing with objects, you want to ignore simple id's as much as convenient.
If you change the click line to this, I think you will be well on your way:
<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu(tutorial)" ng-repeat="tutorial in section.tutorials">
Also, I think you may need to change
class="tutorial_title {{tutorial.active}}"
to something like
ng-class="tutorial_title {{tutorial.active}}"
See http://docs.angularjs.org/misc/faq and look for ng-class.