Подтвердить что ты не робот

Angular фильтровать объект по его свойствам

У меня есть объект с рядом свойств объекта, который находится в следующей подобной структуре (то есть, как данные возвращаются из службы):

{
  "1": {
    "type": "foo",
    "name": "blah"
  },
  "2": {
    "type": "bar"
  },
  "3": {
    "type": "foo"
  },
  "4": {
    "type": "baz"
  },
  "5": {
    "type": "test"
  }
}

Когда я делаю ng-repeat, я могу перебирать все 5 из этих объектов, что-то вроде:

<div ng-repeat="item in items">{{item.type}}</div>

Однако то, что я действительно хочу сделать, это перебирать только те элементы, которые НЕ являются типом "foo" , а именно 3 итерации вместо 5. Я знаю, что фильтры могут каким-то образом использоваться это, но я не уверен, как это сделать. Я попробовал следующее:

<div ng-repeat="item in items| !filter:{type:'foo'}">{{item.type}}</div>

но это не работает. Фактически, даже делая следующее, чтобы ограничить только 2 объекта (те, у которых есть item.type === "foo" ), он не работает и выполняет 5 итераций:

<div ng-repeat="item in items| filter:{type:'foo'}">{{item.type}}</div>

В сущности, я хочу сделать что-то похожее на:

<div ng-repeat="item in items" ng-if="item.type !=='foo'>{{item.type}}</div>

Однако я знаю, что он не работает.

4b9b3361

Ответ 1

Фильтр работает с массивами, но у вас есть объектный литерал.

Таким образом, вы можете либо преобразовать литерал объекта в массив, либо создать собственный фильтр, чем использовать литерал объекта.

Если вам не нужны эти значения индекса, то преобразование в массив может быть вашим лучшим выбором ( Здесь скрипка с массивом: http://jsfiddle.net/NqA8d/3/):

$scope.items = [{
    "type": "foo",
        "name": "blah"
}, {
    "type": "bar"
}, {
    "type": "foo"
}, {
    "type": "baz"
}, {
    "type": "test"
}];

Если вы хотите сделать фильтр, вот один из способов сделать это:

myApp.filter('myFilter', function () {
    return function (items, search) {
        var result = [];
        angular.forEach(items, function (value, key) {
            angular.forEach(value, function (value2, key2) {
                if (value2 === search) {
                    result.push(value2);
                }
            })
        });
        return result;

    }
});

И эта скрипка: http://jsfiddle.net/NqA8d/5/

Ответ 2

Немного поздно ответить, но это может помочь:

Если вы хотите отфильтровать внука (или глубже) данного объекта, вы можете продолжать строить свою иерархию объектов. Например, если вы хотите отфильтровать "thing.properties.title", вы можете сделать следующее:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter } }">

Вы также можете фильтровать несколько свойств объекта, просто добавив их в свой объект фильтра:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter, id: id_filter } }">

Синтаксис "не равно" немного немного, попробуйте следующее:

<div ng-repeat="thing in things | filter: { properties: { title: '!' + title_filter } }">

Ответ 3

Хотя я согласен с тем, что преобразование вашего объекта может быть лучшим вариантом, вы также можете использовать эту функцию фильтра:

angular.module('app').filter('objectByKeyValFilter', function () {
return function (input, filterKey, filterVal) {
    var filteredInput ={};
     angular.forEach(input, function(value, key){
       if(value[filterKey] && value[filterKey] !== filterVal){
          filteredInput[key]= value;
        }
     });
     return filteredInput;
}});

вот так:

<div ng-repeat="(key, value) in data | objectByKeyValFilter:'type':'foo'">{{key}}{{value.type}}</div> 

См. также Plunker.

Ответ 4

Попробуйте это (в контроллере):

$scope.notFooFilter = function(item)
{
    return (item.type !== 'foo');
};

И в разметке HTML:

<div ng-repeat="item in items| filter:notFooFilter">{{item.type}}</div>

Ответ 5

Не нужно этого. Это решение отлично работает без необходимости конвертировать или создавать собственный фильтр:

 {{myModel.userSelectedHour["Start"]}}

Следовательно, object. [ "property" ] вместо object.property.