【问题标题】:Angular JS category filter not working recursivelyAngular JS类别过滤器不能递归工作
【发布时间】:2015-04-10 07:58:00
【问题描述】:

我正在开发一个基于 Angular js 的文件过滤器。现在我在根据类别和相应的子类别过滤结果时遇到了一个问题。如果我选择一个类别 id=a 那么分配给类别 a 及其后代子类别的文件也应该显示出来。任何人请帮我整理一下。这是详细信息。 [ -- 到目前为止,我修复了类别过滤问题,现在问题是每当我选择下拉过滤器时,它都会清除并正确显示结果。请帮我修复它。我已经更新了 plunker 中的代码 http://plnkr.co/edit/fzOzms?p=preview]

JSON

View JSON Input

http://plnkr.co/edit/fzOzms?p=preview

HTML

<div class="filter-wrapper" ng-controller="filterCtrl">
            <div class="filter-wrap">
                <form action="" class="filter">
                    <div class="row">
                        <label class="control-label">{{items.transilations.keywordsearch}}</label>
                        <div class="input-group">
                            <input type="text" class="form-control" ng-model="search" ng-change="filter()" placeholder="{{items.transilations.searchkey}}">
                            <span class="input-group-addon" ng-click="search = ''"></span>
                        </div>
                    </div>
                    <div class="row">
                        <label class="control-label">{{items.transilations.filterbyarea}}</label>                   
                        <div class="input-group">
                            <custom-select ng-repeat="cat in categories track by $index" class="inline-table" style="display:table;"></custom-select>
                        </div>
                    </div>
                    <div class="row">
                        <label class="control-label">{{items.transilations.searchbytype}}</label>
                        <div ng-repeat="type in items.types">
                            <label class="control-label">
                                <input type="checkbox" ng-model="checkFilter[type.id]" value="{{type.id}}">
                                {{type.title}}
                            </label>
                        </div>
                    </div>
                </form>
            </div>
            <div class="result-wrap">
                <h3><span id="total-count"></span> {{items.transilations.resultsfound}}</h3>
                <table id="data-results" class="results">
                    <thead>
                        <tr>
                            <th></th>
                            <th class="item-title">
                                <a href="" ng-click="orderByField='title'; reverseSort = !reverseSort">
                                    {{items.transilations.tabletitle}} 
                                    <span ng-show="orderByField == 'title'">
                                        <span ng-show="!reverseSort"><i class="fa fa-caret-up"></i></span>
                                        <span ng-show="reverseSort"><i class="fa fa-caret-down"></i></span>
                                    </span>
                                </a>
                            </th>                   
                            <th>
                                <a href="" ng-click="orderByField='size'; reverseSort = !reverseSort">
                                    {{items.transilations.tablesize}}
                                    <span ng-show="orderByField == 'size'">
                                        <span ng-show="!reverseSort"><i class="fa fa-caret-up"></i></span>
                                        <span ng-show="reverseSort"><i class="fa fa-caret-down"></i></span>
                                    </span>
                                </a>
                            </th>
                            <th>
                                <a href="" ng-click="orderByField='fileType'; reverseSort = !reverseSort">
                                    {{items.transilations.tabletype}}
                                    <span ng-show="orderByField == 'fileType'">
                                        <span ng-show="!reverseSort"><i class="fa fa-caret-up"></i></span>
                                        <span ng-show="reverseSort"><i class="fa fa-caret-down"></i></span>
                                    </span>
                                </a>
                            </th>
                            <th class="download">{{items.transilations.tabledownload}}</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr dir-paginate ="file in items.files | filter:dummyCategory | filter:byTypes | filter:search |  orderBy:orderByField:reverseSort | offset:0 | itemsPerPage: pageSize" current-page="currentPage">
                            <td class="item-image" data-th="Image"><img class="img-thumbnail" ng-src="{{base}}{{file.imageUrl}}"></td>
                            <td class="item-title" data-th="{{items.transilations.tabletitle}}">{{file.title}}</td>                 
                            <td data-th="{{items.transilations.tablesize}}">{{file.size}}</td>
                            <td data-th="{{items.transilations.tabletype}}">{{file.fileType}}</td>
                            <td class="download" data-th="{{items.transilations.tabledownload}}"><a target="_blank" ng-href="http://192.168.0.207/usterch/{{file.url}}"><img src="save.png"/></a></td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <div class="other-controller">
                <div class="text-center">
                    <dir-pagination-controls boundary-links="true" on-page-change="pageChangeHandler(newPageNumber)" template-url="js/dirPagination/dirPagination.tpl.html">
                    </dir-pagination-controls>
                </div>
            </div>
        </div>

Angular JS 代码

app.directive("subcat", function($compile, $timeout){
    return {
        restrict:"A",
        scope:true,
        link:function(scope,element,attr){
            element.bind("change",function($index){ 
                $timeout(function(){
                    scope.dummyCategory.categories = [scope.dummyCategory.categories];
                    $(element).children('option:selected').attr('data-newVal', scope.dummyCategory.categories);
                    $(element).children('option:selected').attr('data-resetClear', JSON.stringify(scope.dummyCategory));
                    if(scope.dummyCategory.categories == null){
                        if($(element).parent().prev('custom-select').length){
                            scope.dummyCategory.categories= $(element).parent().prev('custom-select').find('option:selected').attr('data-newVal');
                        }
                        else{
                            scope.dummyCategory.categories="";
                        }
                    }
                    var newValue = scope.cat.val.filter(function(item)  {
                        return item.id == scope.dummyCategory.categories
                    });
                    if(newValue[0] && 'input' in newValue[0]){                      
                        getVal(scope, newValue[0]);
                        scope.newArray({categories:scope.dummyCategory,val:newValue[0].input,index:scope.$index});
                        element[0].blur();                      
                    }
                    else{
                        scope.removeArray(scope.$index);
                    }
                    scope.changeCat(scope.dummyCategory);
                }, 100, true);  
            });         
        }
    }
});

function getVal(scope, newValue){   
    var testArray = {testval:newValue.input};   
    var tvLength = testArray.testval.length;
    for(var i=0; i<tvLength; i++){
        scope.dummyCategory.categories.push(testArray.testval[i].id);
        if(testArray.testval[i].input){
            getVal(scope, testArray.testval[i]);
        }   
    }
    return scope.dummyCategory.categories;
}

Server Link

Plunker:http://plnkr.co/edit/3YCTRsKxQ05cuy3czTIb?p=preview

【问题讨论】:

  • 您使用的是哪个版本的 Angular?
  • @Sam: AngularJS v1.3.14
  • 现在有点忙,但我建议你使用一个函数作为过滤器,它也可以让你返回子元素。请参阅此处的示例:codepen.io/anon/pen/GgYzze 您还可以使用以下方法加速过滤器:github.com/a8m/angular-filter#filterby
  • 我已经遇到过这样的事情,你可以把完整的例子放在 Plunker 上吗?
  • @Raeef: plnkr.co/edit/fzOzms?p=preview 。到目前为止,我做到了这一点。现在的问题是每当我尝试过滤复选框时自动清除请帮助我修复。

标签: javascript jquery angularjs angularjs-directive angularjs-filter


【解决方案1】:

您可以使用 Angular 过滤器而不是创建指令,这是一个示例:

JSON:

{
    categories: [{
        id: 1
        name: "cat1"
    }, {
        id: 2
        name: "cat2"
    }]

    files: [{
        id: 1,
        cat_id: 1,
        name: "file1"
    }, {
        id: 2,
        cat_id: 1,
        name: "file2"
    }, {
        id: 3,
        cat_id: 2,
        name: "file3"
    }, {
        id: 4,
        cat_id: 2,
        name: "file1"
    }]
}

HTML:

<div ng-app="ExampleApp" ng-controller="ExampleCtrl">
    <select ng-model="cat_id" ng-options="cat.id as cat.name for cat in categories">
        <option value="">Select...</option>
    </select>
    <select ng-model="file_id" ng-options="file.id as file.name for file in files | filter:{cat_id: cat_id}:comparator">
        <option value="">Select...</option>
    </select>
</div>

JS:

angular.module('ExampleApp', [])

.controller('ExampleCtrl', ['$scope', function($scope) {
    $scope.comparator = function(actual, expected) {
        // comparison here is '==' which is not the same as angular comparison '===', because sometimes the data type is not equal
        return actual == expected;
    };
}]);

当然,您可以根据需要添加过滤器以适合您的应用。

【讨论】:

  • 感谢您的宝贵回答,我会检查并回复。
  • Refal:您能解释一下在过滤中如何考虑类别的子项吗?我的意思是如果猫 id 1 有孩子的猫 id 4,5。如果我选择类别 1,则过滤器在过滤文件时应考虑 1、4、5 个类别。
  • 嗯嗯。好吧,您的示例比我提供的要复杂,老实说,我没有足够的时间为您制作它,但是仍然可以使用过滤器来完成,方法是在选择并删除时将每个子类别 id 推送到一个数组中它在更改其父级时,然后根据包含类别及其子 ID 的数组过滤文件。希望对您有所帮助。
  • Refal:其实我很清楚你解释的逻辑。但问题是我不知道如何在 Angular JS 中实现它。你能告诉我任何其他的例子吗?
猜你喜欢
  • 2015-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 1970-01-01
  • 2021-08-08
  • 2014-05-05
  • 2017-05-21
相关资源
最近更新 更多