Still pretty new with Angular, just finding my way around.
I'm using ng-repeat to output an alphabetised list of names. I'd like to add dividers within this list that act as labels.
Example:
--------
A
--------
Author 1
Author 2
--------
B
--------
Author 3
Author 4
etc
My thinking is to use nested ng-repeats to loop through the alphabet, getting an object with the authors for that specific letter with a second ng-repeat. Here's what I have so far:
<div data-ng-repeat="letter in alphabet">
<div class="item item-divider">
{{letter}}
</div>
<ul>
<li data-ng-repeat="speaker in GetSpeakers(letter)" type="item-text-wrap" href="#/speaker/{{speaker.ID}}">
{{speaker.title}}
</li>
</ul>
</div>
Controller code:
.controller('SpeakersCtrl', function($scope, $routeParams, StorageHandler) {
$scope.GetSpeakers = function(letter) {
// Get list of authors for that letter
console.log('test '+letter);
};
$scope.alphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
})
Fiddle: http://jsfiddle.net/t6Xq8/
I have a couple of questions.
- In general, is using a nested ng-repeat a good approach for this problem, or does Angular have built-in specifically for this purpose? Some sources also say using a function in ng-repeat is a bad idea. But it does work so I'm confused as to why I shouldn't use this.
- When looking at the console, GetSpeakers gets called twice in this example and I can't figure out why?
- How should I return an object to the scope within the GetSpeakers function, while preventing overloading the $scope?
Likely better to map the data into a single object where the object keys are the letter. I'll assume you have objects like:
and want the letter to represent last names
Now in markup will
ng-repeat
all the letters in the object keys, and within that loop, do anng-repeat
of the authors array for that letterResulting object will look like:
I believe that using nested ng repeats is perfectly fine. Im not familiar with a better way that angularjs provides to iterate over multi dimensional arrays/data structures.
The reason you should avoid using functions in ng repeats is that angularjs will call that function each time it will create the element in the repeat directive. As charlie suggested above it would be better to order the authors once and use the resulting array each time, rather than ordering the authors each time you display them. This has the added benefit of being able to reuse the array
I think you can do this in a much simpler way without:
ng-repeat
by using
$index
.so that would look something like this:
This would need a simple function to get the first letter such as:
So what this does is it compares the first letter of whatever you passed to the previous object's first letter and if they are different it adds the divider with that letter. Pretty clean and simple :)
Check out this working JsFiddle
You can obviously improve on that code to handle upper/lowercase (i.e. always capitalize before comparing) as well as extract the comparison into a function for cleaner code.