Angular:使用分隔符/分隔符获取ng-repeat列表

时间:2013-12-31 01:28:08

标签: angularjs angularjs-ng-repeat

对于Angular来说还是一个新手,只是找到了解决方法。

我正在使用ng-repeat输出字母表的名称列表。我想在此列表中添加作为标签的分隔符。

示例:

--------
A
--------
Author 1
Author 2

--------
B
--------
Author 3
Author 4
etc

我的想法是使用嵌套的ng-repeats遍历字母表,通过第二次ng-repeat获取作者的特定字母的对象。这是我到目前为止所做的:

<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('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'];
})

小提琴:http://jsfiddle.net/t6Xq8/

我有几个问题。

  1. 一般来说,使用嵌套的ng-repeat是一种很好的方法 问题,或Angular是否专门为此目的而内置? Some sources也说在ng-repeat中使用函数是一个坏主意。但它确实有效,所以我很困惑为什么我不应该使用它。
  2. 在查看控制台时,GetSpeakers会在此示例中被调用两次,我无法找出原因?
  3. 如何在GetSpeakers函数中将对象返回到作用域,同时防止$ scope超载?

3 个答案:

答案 0 :(得分:12)

我认为如果没有:

,你可以用更简单的方式做到这一点
  • 必须执行嵌套ng-repeat
  • 写出整个字母
  • 需要处理没有作者的信件
  • 操纵原始对象数组或复制它
  • 编写更少的代码行

使用$index

所以看起来像这样:

<div ng-repeat="speaker in speakers | orderBy : 'name'">
    <div class="item item-divider" ng-if="firstLetter(speaker.name) != firstLetter(speakers[$index-1].name)">
      {{firstLetter(speaker.name)}}
    </div>
    {{speaker.name}}
</div>

这需要一个简单的函数来获取第一个字母,如:

function firstLetter(name) {
  return name && name.charAt(0);
}

所以它的作用是比较你传递给前一个对象的第一个字母的第一个字母,如果它们不同,则将该分隔符添加到该字母。非常干净和简单:)

查看此工作JsFiddle

您可以明显改进该代码以处理大写/小写(即在比较之前始终大写)以及将比较提取到更清晰代码的函数中。

答案 1 :(得分:11)

将数据映射到对象键为字母的单个对象可能更好。我假设你有像这样的对象:

{id:123, firstName:'Frank',lastName :'Enstein'} 

并希望这封信代表姓氏

var tmp={};
for(i=0;i<authourArray.length;i++){
    var letter=authourArray[i].lastName.charAt(0);
   if( tmp[ letter] ==undefined){
        tmp[ letter]=[]
   }
     tmp[ letter].push( authourArray[i] );
}

/* likely want to loop over all the arrays now and sort unless already sorted from server*/

$scope.repeaterObject=tmp;

现在在标记中将ng-repeat对象键中的所有字母,并在该循环内,为该字母执行作者数组的ng-repeat

<div data-ng-repeat="(letter, authors) in repeaterObject">
    <div class="item item-divider">
        {{letter}}
    </div>
    <ul>
        <li ng-repeat="author in authors">{{author.firstName}} {{author.lastName}}</li>
    </ul>
</div>

结果对象如下:

{
   A:[.....],
   ......
   E:[ {id:123, firstName:'Frank',lastName :'Enstein'}, /* other E author objects*/ ],
   ......
}

答案 2 :(得分:1)

我相信使用嵌套的ng重复是完全正常的。我不熟悉angularjs提供迭代多维数组/数据结构的更好方法。

你应该避免在ng重复中使用函数的原因是angularjs每次在repeat指令中创建元素时都会调用该函数。正如查理在上面所建议的那样,最好每次对作者进行排序并使用结果数组,而不是每次显示时都要对作者进行排序。这具有能够重用数组

的额外好处