在Angular js中按类名过滤匹配的元素。

时间:2015-08-14 09:59:58

标签: javascript json angularjs ng-repeat

问题:

我有一个无序的项目列表,这些项目是从json调用返回的,并使用ng-repeat输出。这些项目中的每一项都有一个类名(大约有9个类别)。

我有第二个无序列表,它只是一个可用类别列表。

目标:

我希望能够选择右侧列表中的一个类别,这会将过滤器应用于返回元素的实际列表。这应该通过切换激活(因此单击一次:过滤,再次单击:删除过滤器)。因此,它只是希望将单击元素中的类名与json数据列表中共享相同类名的元素相匹配。

我不能使用ng-model(因为这是为某些表单元素保留的)。

对于我的jsfiddle,我只是使用静态html。

这是我的角度代码:

/* angular custom filter on returned ajax api data */
var app = angular.module('app', []);

app.controller('main', function($scope) {
    $scope.chFilters = {};

    $scope.links = [
        {name: 'atm'},
        {name: 'internet'},
        {name: 'mobile'},
        {name: 'sms'},
        {name: 'postal'}
    ];

    $scope.channels = ["ATM", "INTERNET", "SMS", "POSTAL","MOBILE"];

});

(这是基于我在SO上发现的另一个问题)。不幸的是,小提琴有点乱,并且有一些无关的代码。

HTML:

<div ng-app="app">
    <div ng-controller="main">
        <ul>
            <li class="atm">Some stuff ATM</li>
            <li class="internet">Some stuff INTERNET</li>   
            <li class="sms">Some stuff ATM</li>   
            <li class="atm">Some stuff ATM</li>   
            <li class="postal">Some stuff POSTAL</li>   
            <li class="atm">Some stuff ATM</li>   
            <li class="internet">Some stuff INTERNET</li>   
            <li class="postal">Some stuff POSTAL</li>   
            <li class="postal">Some stuff POSTAL</li>   
            <li class="atm">Some stuff ATM</li>   
            <li class="sms">Some stuff SMS</li>   
            <li class="mobile">Some stuff MOBILE</li>   
            <li class="internet">Some stuff INTERNET</li>   
            <li class="mobile">Some stuff MOBILE</li>   
        </ul>

        <ul class="channel-filters">
            <li ng-repeat="link in links | filter:chFilters" class="{{link.name | lowercase}}"><a ng-click="chFilters.name = link.name">{{link.name | uppercase}}</a></li>
            <li class="last" ng-click="chFilters.name = ''">CLEAR FILTER</li>
        </ul>

        <ul>
            <li ng-repeat="channel in channels | filter:chFilters">
                <strong>{{channel}}</strong>
                <a ng-click="chFilters = channel">{{channel}}</a>
            </li>
        </ul>

        <!-- original -->
        <ul>
            <li ng-repeat="link in links | filter:chFilters">
                <strong>{{link.name}}</strong>
                <a ng-click="chFilters.name = link.name">{{link.name}}</a>
            </li>
        </ul>
    </div>
</div>

这是应用程序的实际HTML(调用api)。

<ul class="accordion">
    <li class="search-text-channel">
        <input type="textarea" ng-model="searchTextChannel.$" placeholder="Search"/>
    </li>
    <li ng-repeat="day in interactions.model.byDay | filter:searchTextChannel" ng-click="hidden = !hidden" ng-init="hidden = false" class="{{day.channel | removeSpace | lowercase}}" ng-class="{'closed': !hidden, 'open': hidden}">
        <span class="date">{{day.date}}</span>
        <span class="subheading">{{day.channel}}</span>
        <ul ng-show="hidden">
            <li ng-repeat="interaction in day.interactions">
                {{interaction.time}} {{interaction.description | removeUnderscore}}
            </li>
        </ul>
    </li>
    <li class="load-more">
        <a href="" ng-click="interactions.loadMore()"><i class="fa fa-plus"></i>LOAD MORE</a>
    </li>
</ul>

我已经设法在jquery中重新创建了这个功能,但我认为在角度应用程序中实现角度解决方案会更好。

我尝试过研究并试图实现show / hide以及自定义过滤器,但到目前为止还没有任何乐趣。

这是我的(凌乱)jsfiddle

2 个答案:

答案 0 :(得分:1)

<ul>
    <li ng-repeat="channel in channels | filter:chFilters.name">
        <strong>{{channel}}</strong>
        <a ng-click="chFilters = channel">{{channel}}</a>
    </li>
</ul>
<!-- original -->
<ul>
    <li ng-repeat="link in links | filter:chFilters.name">
        <strong>{{link.name}}</strong>
        <a ng-click="chFilters.name = link.name">{{link.name}}</a>
    </li>
</ul>

更新Plunker

如果您对此有任何疑问,请与我们联系。

答案 1 :(得分:0)

以下是解决方案的一部分:

假设您的商品如下所示:

$scope.items = [
    { class: "atm", label: "Some stuff ATM" },
    { class: "internet", label: "Some stuff INTERNET" },
    { class: "sms", label: "Some stuff SMS" },
    { class: "postal", label: "Some stuff POSTAL" },
    ...
];

显示已过滤的列表(目前仅按单个频道进行过滤):在范围内创建一个单独的列表,并应用过滤器:

$scope.click = function(name) {
    $scope.chFilters.name = name;
    $scope.filteredItems = $scope.items.filter(function(item) {
        return item.class === $scope.chFilters.name;
    });
};

从底部列表中调用此单击处理程序:

...<a ng-click="click(link.name)">{{link.name | uppercase}}</a>....

在顶部列表中显示filteredItems

<ul>
  <li ng-repeat="item in filteredItems" ng-class="item.class">{{item.label}}</li>
</ul>

所以这只是一个起点,它应该扩展到处理多个过滤器等......