简体   繁体   English

在NG-repeat上使用对象作为过滤器

[英]Using a object on NG-repeat as a filter

I have a multiple select dropdowns which are generated from a JSON file of categories. 我有多个选择下拉列表,这些下拉列表是根据类别的JSON文件生成的。

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. 我想使用用户在选择中所做的选择来筛选由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. 我有这个笨拙的人http://plnkr.co/edit/ipfVfH3pbLoYk1u4n3la?p=preview ,其中显示了生成的下拉列表,但用户选择进入了一个对象,从我的得知,您不能将其用作ng-repeat的过滤器。

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 这是来自我的较早的文章- 从单个JSON文件动态创建多个下拉Angularjs

Here's an alternate version rendering each select individually. 这是一个替代版本,分别呈现每个选择。 It's using a custom groupBy filter (using underscore): 它使用自定义的groupBy过滤器(使用下划线):

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. 因为如果直接与ng-repeat一起使用,angular将抱怨无限$ digest循环。

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. http://i.imgur.com/1SxjxFC.jpg-抱歉,这并不会让我获得更高质量的屏幕截图。

The ng repeat i currently have for the apps is; 我目前对这些应用程式的ng重复是:

        <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. 每个应用程序可以具有1个或多个标签,所有标签都可以在生成的下拉菜单中进行过滤。

As you can see from the image posted the user can filter down by selecting multiple categories from any of the categoryTypes they want. 从发布的图像中可以看到,用户可以通过从所需的任何categoryTypes中选择多个类别来进行过滤。 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. 我不能真正使用group by,因为涉众希望每个过滤器下拉列表都分开,然后允许用户从1个或多个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 cb-只是在控制器中的成功回调

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. 我想发生的是,随着用户选择过滤器,就像angularjs文本搜索演示一样,每次进行选择时它都会过滤出应用程序,并且当用户单击x并从过滤器列表中删除类别时,它将删除所有应用程序由于该选择而被显示。 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 获取所选的categoryNames
  2. filtering the apps by computing the difference to the selected categories 通过计算与所选类别的差异来过滤应用

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM