Làm cách nào để lọc (khóa, giá trị) với ng-repeat trong AngularJs?


113

Tôi đang cố gắng làm điều gì đó như:

<div ng-controller="TestCtrl">
    <div ng-repeat="(k,v) in items | filter:hasSecurityId">
        {{k}} {{v.pos}}
    </div>
</div>

Phần AngularJs:

function TestCtrl($scope) 
{
    $scope.items = {
                     'A2F0C7':{'secId':'12345', 'pos':'a20'},
                     'C8B3D1':{'pos':'b10'}
                   };

    $scope.hasSecurityId = function(k,v)
    {
       return v.hasOwnProperty('secId');
    }
}

Nhưng bằng cách nào đó, nó đang hiển thị cho tôi tất cả các mục. Làm cách nào để lọc (khóa, giá trị)?


xin vui lòng cung cấp một số mục dữ liệu ví dụ fot. Hoặc cho chúng tôi một trò đùa;)
Robin Drexler

Đây không phải là cách bạn tạo một bộ lọc xem các tài liệu , và như Robin đã nói, hãy lấy một ví dụ.
Yahya KACEM

Tôi đã đưa ra một ví dụ đầy đủ và tôi biết cách sử dụng các bộ lọc. Tôi chỉ hỏi "cách sử dụng bộ lọc với (khóa, giá trị)".
Vural

chỉ số và số lượng nên có sẵn trong phạm vi mà iirc
Shanimal

Câu trả lời:


131

Bộ lọc góc chỉ có thể được áp dụng cho mảng chứ không phải đối tượng, từ API của góc -

"Chọn một tập hợp con các mục từ mảng và trả về nó dưới dạng một mảng mới."

Bạn có hai tùy chọn ở đây:
1) di chuyển $scope.itemsđến một mảng hoặc -
2) lọc trước các ng-repeatmục, như sau:

<div ng-repeat="(k,v) in filterSecId(items)">
    {{k}} {{v.pos}}
</div>

Và trên Bộ điều khiển:

$scope.filterSecId = function(items) {
    var result = {};
    angular.forEach(items, function(value, key) {
        if (!value.hasOwnProperty('secId')) {
            result[key] = value;
        }
    });
    return result;
}

jsfiddle : http://jsfiddle.net/bmleite/WA2BE/


9
Người ta cần phải cẩn thận với cách tiếp cận này để tránh các vòng lặp (tiêu hóa) vô hạn. Xem 6054705 . Tóm tắt bởi Narretz : Nói tóm lại, sử dụng các hàm để trả về bộ sưu tập trong ng-repeat là một cách chống lại. Tốt hơn là gán bộ sưu tập cho một thuộc tính phạm vi và lặp lại điều đó.
Joe23

3
Bình luận hữu ích. Điều này đã ném tôi cho một vòng lặp; Tôi mong đợi có thể lọc bất kỳ tệp nào có thể lặp lại. Cảm ơn nhiều. :)
Chris Krycho

3
Lưu ý: Đây là mẫu chống hoàn hảo hiện nay. Angular 1.3 hiện có các bộ lọc không trạng thái ( egghead.io/lessons/… ) nên bạn chắc chắn muốn tạo một bộ lọc cho việc này.
kentcdodds

8
@kentcdodds không đăng các liên kết không miễn phí!
Sebastian

11
Tại sao không chỉ thêm ng-if vào phần tử lặp lại?
CarbonDry

45

Giải pháp của tôi sẽ là tạo bộ lọc tùy chỉnh và sử dụng nó:

app.filter('with', function() {
  return function(items, field) {
        var result = {};
        angular.forEach(items, function(value, key) {
            if (!value.hasOwnProperty(field)) {
                result[key] = value;
            }
        });
        return result;
    };
});

Và trong html:

 <div ng-repeat="(k,v) in items | with:'secId'">
        {{k}} {{v.pos}}
 </div>

1
tuy nhiên, nó sẽ lặp n * n lần.
maxisam

27

Ngoài ra, bạn có thể sử dụng ng-repeatvới ng-if:

<div ng-repeat="(key, value) in order" ng-if="value > 0">

2
Tài giỏi. Điều này đã tiết kiệm rất nhiều thời gian.
Safwan


11

Bạn chỉ có thể sử dụng mô-đun angle.filter và sau đó bạn có thể lọc theo các thuộc tính lồng nhau.
xem: jsbin
2 Ví dụ:

JS:

angular.module('app', ['angular.filter'])
  .controller('MainCtrl', function($scope) {
  //your example data
  $scope.items = { 
    'A2F0C7':{ secId:'12345', pos:'a20' },
    'C8B3D1':{ pos:'b10' }
  };
  //more advantage example
  $scope.nestedItems = { 
    'A2F0C7':{
      details: { secId:'12345', pos:'a20' }
    },
    'C8B3D1':{
      details: { pos:'a20' }
    },
    'F5B3R1': { secId:'12345', pos:'a20' }
  };
});

HTML:

  <b>Example1:</b>
  <p ng-repeat="item in items | toArray: true | pick: 'secId'">
    {{ item.$key }}, {{ item }}
  </p>

  <b>Example2:</b>
  <p ng-repeat="item in nestedItems | toArray: true | pick: 'secId || details.secId' ">
    {{ item.$key }}, {{ item }}
  </p> 

21
Bạn nên tiết lộ rằng đó angular.filterkhông phải là một mô-đun góc cạnh cốt lõi và bạn là tác giả của nó.
demisx

Có vẻ như toArraybộ lọc không còn tồn tại nữa. Có phải thay thế không, vì filterbộ lọc vẫn không cho phép các đối tượng?
chạy thận

6

Hơi muộn, nhưng tôi đã tìm kiếm bộ lọc tương tự và kết thúc bằng cách sử dụng một cái gì đó như thế này:

<div ng-controller="TestCtrl">
 <div ng-repeat="(k,v) in items | filter:{secId: '!!'}">
   {{k}} {{v.pos}}
 </div>
</div>

2
Làm thế nào bạn có được điều này để làm việc? Khi tôi sử dụng bộ lọc với một đối tượng ng-lặp lại, tôi gặp lỗi, đó là lỗi được mong đợi dựa trên tài liệu Angular.
tonestrike, 29/09/17

1

Mặc dù câu hỏi này khá cũ, nhưng tôi muốn chia sẻ giải pháp của mình cho các nhà phát triển góc 1. Vấn đề là chỉ sử dụng lại bộ lọc góc ban đầu, nhưng chuyển trong suốt bất kỳ đối tượng nào dưới dạng mảng.

app.filter('objectFilter', function ($filter) {
    return function (items, searchToken) {
        // use the original input
        var subject = items;

        if (typeof(items) == 'object' && !Array.isArray(items)) {
            // or use a wrapper array, if we have an object
            subject = [];

            for (var i in items) {
                subject.push(items[i]);
            }
        }

        // finally, apply the original angular filter
        return $filter('filter')(subject, searchToken);
    }
});

sử dụng nó như thế này:

<div>
    <input ng-model="search" />
</div>
<div ng-repeat="item in test | objectFilter : search">
    {{item | json}}
</div>

đây là một plunker


0

Tôi đã tạo thêm một chút về bộ lọc chung mà tôi đã sử dụng trong nhiều dự án:

  • object = đối tượng cần được lọc
  • field = trường bên trong đối tượng mà chúng tôi sẽ lọc
  • filter = giá trị của bộ lọc cần khớp với trường

HTML:

<input ng-model="customerNameFilter" />
<div ng-repeat="(key, value) in filter(customers, 'customerName', customerNameFilter" >
   <p>Number: {{value.customerNo}}</p>
   <p>Name: {{value.customerName}}</p>
</div>

JS:

  $scope.filter = function(object, field, filter) {
    if (!object) return {};
    if (!filter) return object;

    var filteredObject = {};
    Object.keys(object).forEach(function(key) {
      if (object[key][field] === filter) {
        filteredObject[key] = object[key];
      }
    });

    return filteredObject;
  };
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.