离子动态列表分割器

时间:2014-11-01 22:48:52

标签: angularjs cordova ionic-framework

我已经被这个问题困扰了一段时间了,所以我希望你能让我朝着正确的方向前进。

我的角度工厂返回一个看起来像这样的对象

[{
    name:"Fall",
    year:"20xx",
    id: some_id_#
}, ....]

这是一个学期列表,每个学期都有一个包含姓名,年份和学期ID的对象。 我正在使用ionic作为我的UI框架,我想将我的HTML输出设置为这样......

2012
  秋季
  春天
2013
  冬季
  春天
2014
  等
  等

每年都是列表分隔符。我的HTML目前看起来像这样

<ion-list show-delete="data.showDelete">
    <!-- I WAN TO CHANGE THIS TO BE A DYNAMIC HEADER ADDED FOR EACH NEAR YEAR-->
    <ion-item class="item-divider">
        Semesters
    </ion-item>

    <ion-item ng-show="semesters.length == 0">
        No semesters yet!
    </ion-item>
    <ion-item class="item-dark item-icon-right" href="#/app/class-list/{{semester.id}}/{{semester.name}}/{{semester.year}}" ng-repeat="semester in semesters">
        <ion-delete-button class="ion-ios7-trash-outline"
                   ng-click="deleteSemester(semester)">
        </ion-delete-button>
        {{semester.name}} {{semester.year}}
        <i class="icon ion-ios7-arrow-forward"></i>
    </ion-item>
</ion-list>

我不喜欢用逻辑混淆我的观点,因为它属于控制器,但我不知道该怎么做,啊哈。

谢谢你们!

3 个答案:

答案 0 :(得分:6)

我不确定这是否是最佳方式,但我建立了一个CodePen来实现这一目标:

  • 获取原始列表(这将是您的真实数据)
  • 通过为唯一起始字母创建其他项目来修改列表
  • 在视图中,我们查看我们的数据是否为字母,如果是,则将其视为列表分隔符

这有点像他们的笔之一(http://codepen.io/ionic/pen/uJkCz)。我觉得有些不对劲,但似乎运作良好。这是控制器部分:

.controller('RootCtrl', function($scope) {

  //orig data
  var list = [];
  list.push({name:"Gary"});
  list.push({name:"Gosh"});
  list.push({name:"Ray"});
  list.push({name:"Sam"});
  list.push({name:"Sandy"});

  $scope.list = [];
  var lastChar = '';
  for(var i=0,len=list.length; i<len; i++) {
    var item = list[i];

    if(item.name.charAt(0) != lastChar) {
      $scope.list.push({name:item.name.charAt(0),letter:true});
      lastChar = item.name.charAt(0);
    }
    $scope.list.push(item);

  }
})

然后视图检查数据是否是人与字母。再次,这感觉有点蹩脚,但是......

<ion-list type="list-inset">
  <ion-item ng-repeat="person in list" ng-class="person.letter? 'item-divider':''">
    {{person.name}}
  </ion-item>
</ion-list>

您可以在此处运行:http://codepen.io/cfjedimaster/pen/HqrBf

答案 1 :(得分:6)

使用UnderscoreJS的另一个解决方案是让你&#34; group&#34;您感兴趣的属性列表(此处为年份),然后您可以在模板中迭代这些组。

短版

在您的控制器中:

$scope.groupedPairs = _.chain(list).groupBy('year').pairs().sortBy(0).value();

在你的模板中:

<ion-list>
    <div ng-repeat="groupedPair in groupedPairs track by groupedPair[0]">
        <ion-item class="item-divider">
            {{groupedPair[0]}}
        </ion-item>
        <ion-item ng-repeat="item in groupedPair[1] track by item.id">
            {{item.name}}
        </ion-item>
    </div>
</ion-list>

长版

首先按照&#39;年份对您的列表进行分组。属性。

var list = [{
    name:"Fall",
    year:"2014"
}, {
    name:"Fall",
    year:"2012"
}, {
    name:"Spring",
    year:"2012"
}, {
    name:"Spring",
    year:"2013"
}, {
    name:"Spring",
    year:"2014"
}, {
    name:"Winter",
    year:"2013"
}];
var grouped = _(list).groupBy('year');

grouped现在是:

{
    "2014": [{
        name:"Fall",
        year:"2014"
    }, {
        name:"Spring",
        year:"2014"
    }],
    "2012": [{
        name:"Fall",
        year:"2012"
    }, {
        name:"Spring",
        year:"2012"
    }],
    "2013": [{
        name:"Spring",
        year:"2013"
    }, {
        name:"Winter",
        year:"2013"
    }]
}

但是现在你想要按年份排序,所以我们需要再做两次操作。

首先,将grouped对象转换为键/值对数组。

var pairs = _(grouped).pairs();

pairs现在是:

[
    [
        "2014",
        [{
            name:"Fall",
            year:"2014"
        }, {
            name:"Spring",
            year:"2014"
        }]
    ],
    [
        "2012",
        [{
            name:"Fall",
            year:"2012"
        }, {
            name:"Spring",
            year:"2012"
        }]
    ],
    [
        "2013",
        [{
            name:"Spring",
            year:"2013"
        }, {
            name:"Winter",
            year:"2013"
        }]
    ]
]

现在我们只需要按&#34;键&#34;在每个键/值对中。换句话说,每对的[0]属性(包含分组的年份,例如"2013"):

var sortedPairs = _(pairs).sortBy(0);

sortedPairs现在是:

[
    [
        "2012",
        [{
            name:"Fall",
            year:"2012"
        }, {
            name:"Spring",
            year:"2012"
        }]
    ],
    [
        "2013",
        [{
            name:"Spring",
            year:"2013"
        }, {
            name:"Winter",
            year:"2013"
        }]
    ],
    [
        "2014",
        [{
            name:"Fall",
            year:"2014"
        }, {
            name:"Spring",
            year:"2014"
        }]
    ]
]

...可以在模板中轻松迭代。鉴于$scope.groupedPairs = sortedPairs;

<ion-list>
    <div ng-repeat="groupedPair in groupedPairs track by groupedPair[0]">
        <ion-item class="item-divider">
            {{groupedPair[0]}}
        </ion-item>
        <ion-item ng-repeat="item in groupedPair[1] track by item.id">
            {{item.name}}
        </ion-item>
    </div>
</ion-list>

以及将var list转换为$scope.groupedPairs的完整控制器代码,但没有全部解释:

$scope.groupedPairs = _.chain(list).groupBy('year').pairs().sortBy(0).value();

答案 2 :(得分:1)

此解决方案使用ng-repeat别名功能显示日期对象的分组日期分隔符。这个解决方案的关键是分频器上的ng-if。注意日期周围的括号:'yyyy'过滤比较,如果前一结果年不等于当前结果年,则仅将分隔符添加到DOM。它显示一个分组的分隔符。

<ion-list show-delete="data.showDelete"
          ng-repeat="semester in semesters as results">

    <ion-item class="item-divider"
              ng-if="(results[$index-1].year|date:'yyyy') !== (results[$index].year|date:'yyyy')">
        {{results[$index].year|date:'yyyy'}}
    </ion-item>

    <ion-item ng-show="results.length == 0">
        No semesters yet!
    </ion-item>
    <ion-item class="item-dark item-icon-right" href="#/app/class-list/{{semester.id}}/{{semester.name}}/{{semester.year}}">
        <ion-delete-button class="ion-ios7-trash-outline"
                   ng-click="deleteSemester(semester)">
        </ion-delete-button>
        {{semester.name}} {{semester.year}}
        <i class="icon ion-ios7-arrow-forward"></i>
    </ion-item>
</ion-list>