使用 NG-repeat 上的对象作为过滤器 [英] Using a object on NG-repeat as a filter

查看:23
本文介绍了使用 NG-repeat 上的对象作为过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多个选择下拉列表,它们是从类别的 JSON 文件生成的.

我想使用用户在选择中做出的选择来过滤使用 ng-repeat 生成的应用列表.

我有这个 plunker http://plnkr.co/edit/ipfVfH3pbLoYk1u4n3la?p=preview 显示生成的下拉列表,但用户选择进入一个对象,据我所知,您不能将其用作 ng-repeat 的过滤器.

是否可以使用它来过滤或我可以转换它?

这是我之前的一篇文章 - 从单个 JSON 文件动态创建多个下拉菜单 angularjs

这是单独呈现每个选择的替代版本.它使用自定义 groupBy 过滤器(使用下划线):

app.filter('groupBy', ['$parse', function ($parse) {返回函数 groupByFilter(input, groupByExpr) {返回 _.groupBy(input, $parse(groupByExpr));};}]);

与:

<label>{{categoryTypeName}}</label><选择ng-model="已选择 [categoryTypeName]"ng-options="c as c.name for c in category track by c.id"多></选择>

不幸的是,当数据发生变化时必须应用过滤器,

$scope.$watchCollection('categories', function (categories) {$scope.groupedCategories = groupByFilter(categories, 'categoryType.name');});

因为如果直接与 ng-repeat 一起使用,angular 会抱怨无限的 $digest 循环.

那么是否可以使用输出(用户选择)作为重复的过滤器?

我需要使用的是选择用于过滤应用程序的类别名称,因此如果应用程序没有使用他们选择的类别进行标记,则它不会显示.每个应用都可以添加下拉菜单中可用的任何标签.

--- 添加信息---

显示的应用程序列表将在与上方和 plunker 中的过滤器相同的控制器中处理,并且它们将在同一视图中,请参阅我当前拥有的图像.模糊的东西出来保护.

http://i.imgur.com/1SxjxFC.jpg - 抱歉它不是让我获得更高质量的屏幕截图.

我目前对应用程序的 ng 重复是;

 

查询只是一个简单的搜索输入框.

要生成用户可以从中做出多项选择的下拉列表,请使用此重复;

<label>{{categoryTypeName}}</label><br><select class="form-control" multiple class="span4 chzn-select" selected data-placeholder=""ng-options="c as c.name for c in category track by c.id"ng-model="已选择 [categoryTypeName]"></选择>

Chosen 只是一个插件,用来让多选看起来不错.

他们可以点击显示的每个应用程序,它会为他们提供有关它的更多详细信息.每个应用程序都可以有 1 个或多个标签,所有这些标签都可以在生成的下拉菜单中进行过滤.

从发布的图片中可以看出,用户可以通过从他们想要的任何 categoryTypes 中选择多个类别来进行过滤.我不能真正使用 group by,因为利益相关者希望每个过滤器下拉列表都分开,然后允许用户选择多个类别以从 1 个或多个 categoryTypes 中过滤.

我必须生成应用程序的控制器看起来像这样;

$scope.objects = [];$scope.getData = 函数 (cb) {返回 appFactory.query(函数(数据){$scope.objects = 数据;如果 (cb) cb();},功能(数据){alert("获取所有应用程序出错");});};$scope.getData();var successCallback = function (e, cb) {alertService.add("成功", "成功!");$scope.getData(cb);};

cb - 只是控制器中的一个成功回调

随着工厂的存在;

.factory('appFactory', function ($resource) {返回$资源('资源/应用商店/应用程序/:id',{ id:'@id' },{'更新':{方法:'PUT'}});})

我想要发生的是,当用户选择过滤器时,就像 angularjs 文本搜索演示一样,它会在每次进行选择时过滤掉应用程序,当用户单击 x 并从过滤器列表中删除一个类别时,它将过滤掉应用程序删除由于该选择而显示的任何应用程序.如果这有意义吗?

我想这就是我需要提供的所有信息,如果我遗漏了更多信息,请告诉我.

解决方案

我认为您将再次需要一个自定义过滤器.尝试例如(再次使用下划线):

app.filter('bySelectedCategories', [function () {返回函数 bySelectedCategoriesFilter(input, selection) {var categoryNames = _.flatten(_.map(selection, function (categories) {return _.pluck(categories, 'name');}));返回_.过滤器(输入,功能(应用程序){返回 _.difference(categoryNames, app.categoryNames).length === 0;});};}]);

这是由:

  1. 获取选定的categoryNames
  2. 通过计算与所选类别的差异来过滤应用

演示:http://plnkr.co/edit/wAyfBgjLBSS0KcN008ru?p=preview

I have a multiple select dropdowns which are generated from a JSON file of categories.

I want to use the choice the users make in the selection to filter a list of apps that are generated with an ng-repeat.

I have this plunker http://plnkr.co/edit/ipfVfH3pbLoYk1u4n3la?p=preview which shows the dropdowns generated but the users choice goes into an object and from what i am told you can not use this as a filter for ng-repeat's.

Is it possible to use this to filter by or can i convert this?

This is from an earlier post of mine - Dynamically create multiple dropdowns angularjs from a single JSON file

Here's an alternate version rendering each select individually. It's using a custom groupBy filter (using underscore):

app.filter('groupBy', ['$parse', function ($parse) {
  return function groupByFilter(input, groupByExpr) {
    return _.groupBy(input, $parse(groupByExpr));
  };
}]);

with:

<div ng-repeat="(categoryTypeName, categories) in groupedCategories track by categoryTypeName">
  <label>{{categoryTypeName}}</label>

  <select
    ng-model="selected[categoryTypeName]"
    ng-options="c as c.name for c in categories track by c.id"
    multiple
  ></select>
</div>

Unfortunately the filter has to be applied when the the data changes,

$scope.$watchCollection('categories', function (categories) {
  $scope.groupedCategories = groupByFilter(categories, 'categoryType.name');
});

because if used with ng-repeat directly angular will complain about an Infinite $digest Loop.

So is it possible to use the output (users choices) as a filter on the repeat?

What i need to use is the name of the category that is chosen to filter the apps so if the app is not tagged with the category they chose then it wont show up. Each app has the ability to add any tags that are available in the dropdowns.

--- ADDED INFORMATION ---

The list of apps displayed will be handled in the same controller as the filters from above and in the plunker and they will be in the same view, see the image as to what i currently have. Blurred things out for protection.

http://i.imgur.com/1SxjxFC.jpg - apologies it's not letting me getting a higher quality screenshot.

The ng repeat i currently have for the apps is;

        <div class="col-md-4"
                            ng-repeat="app in objects | filter:query |orderBy:'-createdAt'">

With query just being a simple search input box.

To generate the dropdowns from which the the user can make multiple choices is using this repeat;

<div ng-repeat="(categoryTypeName, categories) in groupedCategories track by categoryTypeName">
  <label>{{categoryTypeName}}</label>
<br>
  <select  class="form-control" multiple class="span4 chzn-select" chosen data-placeholder=" "
    ng-options="c as c.name for c in categories track by c.id"
    ng-model="selected[categoryTypeName]"

  ></select>

Chosen is just a plugin used to make multiple selection look nice.

Each app that is displayed they can click on and it will give them more details about it. Each app has can have 1 or multiple tags all of which are available to filter by in the dropdown menus which are generated.

As you can see from the image posted the user can filter down by selecting multiple categories from any of the categoryTypes they want. I cant really use the group by as the stakeholders want every filter dropdown to be seperated and then allow the user to choice multiple categories to filter by from 1 or multiple categoryTypes.

The controller i have to generate the apps looks like this;

$scope.objects = [];


  $scope.getData = function (cb) {
            return appFactory.query(function (data) {
                $scope.objects = data;
                if (cb) cb();
            }, function(data) {
                alert("ERROR getting all applications");
            });
        };

$scope.getData();

var successCallback = function (e, cb) {
        alertService.add("success", "Success!");
        $scope.getData(cb);
    };

cb - is just a succesfull callback which is in the controller

With the factory being;

.factory('appFactory', function ($resource) {
        return $resource(
                 'resources/appstore/applications/:id', 
            { id:'@id' }, 
            { 'update': { method: 'PUT'} }  
        );
    })

What i want to happen is as the user choices filters just like the angularjs text search demo it will filter out the apps each time a selection is made and when the user clicks the x and removes a category from the filter list it will remove any apps that were shown because of that choice. If that makes sense?

I think that is all the information i would need to give, if their is still more i have left out please let me know.

解决方案

I think you'll again need a custom filter for this. Try for example (again using underscore):

app.filter('bySelectedCategories', [function () {
  return function bySelectedCategoriesFilter(input, selection) {
    var categoryNames = _.flatten(_.map(selection, function (categories) {
      return _.pluck(categories, 'name');
    }));

    return _.filter(input, function (app) {
      return _.difference(categoryNames, app.categoryNames).length === 0;
    });
  };
}]);

this works by:

  1. getting the selected categoryNames and
  2. filtering the apps by computing the difference to the selected categories

demo: http://plnkr.co/edit/wAyfBgjLBSS0KcN008ru?p=preview

这篇关于使用 NG-repeat 上的对象作为过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆