2013-02-09 20 views
103

Tôi cố gắng để làm một cái gì đó như:Làm thế nào để lọc (khóa, giá trị) với ng-lặp trong AngularJs?

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

AngularJs Phần:

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ó được hiển thị cho tôi tất cả các mục. Làm cách nào tôi có thể lọc (khóa, giá trị)?

+0

vui lòng cung cấp một số dữ liệu ví dụ để chơi bóng các mặt hàng. Hoặc cung cấp cho chúng tôi một fiddle;) –

+0

Đây không phải là cách bạn tạo một bộ lọc nhìn vào [tài liệu] (http://docs.angularjs.org/guide/dev_guide.templates.filters.creating_filters), và như Robin nói, một xin vui lòng. –

+0

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ị)". –

Trả lời

122

góc filters chỉ có thể được áp dụng cho các mảng và không đối tượng, từ API góc của - "Chọn một tập hợp con của các mục từ mảng và trả về nó như là một mảng mới"

Bạn có hai lựa chọn ở đây:
1) di chuyển $scope.items để một mảng hoặc -
2) trước bộ lọc ng-repeat mặt hàng, như thế này:

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

Và trên Controller:

$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/

+8

Một trong những cần phải cẩn thận với phương pháp này để tránh vô hạn (digest) vòng. Xem [6054] (https://github.com/angular/angular.js/issues/6054) và [705] (https://github.com/angular/angular.js/issues/705). Tóm tắt bởi [Narretz] (https://github.com/Narretz): _Trong ngắn hạn, việc sử dụng các hàm trả về bộ sưu tập trong ng-repeat là một mẫu chống. Tốt hơn là chỉ định bộ sưu tập cho thuộc tính phạm vi và lặp lại trên đó._ – Joe23

+3

Nhận xét 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ỳ * lặp lại. Cảm ơn nhiều. :) –

+3

Lưu ý: Đây là mẫu chống hoàn hảo hiện nay. Góc 1.3 có bộ lọc không trạng thái bây giờ (https://egghead.io/lessons/angularjs-new-in-angular-1-3-stateless-filters) vì vậy bạn chắc chắn muốn tạo một bộ lọc cho việc này. – kentcdodds

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

, nó sẽ lặp lại n * n lần. – maxisam

11

Bạn chỉ cần sử dụng mô-đun angular.filter và sau đó bạn có thể lọc ngay cả theo 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.filter' không phải là một mô-đun góc lõi và bạn là tác giả của nó. – demisx

+0

Dường như bộ lọc 'toArray' không còn hiện diện nữa. Có một sự thay thế, bởi vì bộ lọc 'filter' vẫn không cho phép các đối tượng? – trysis

19

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

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

Nó là loại muộn, nhưng tôi nhìn cho e bộ lọc tương tự và kết thúc bằ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> 
+0

Bạn đã làm việc này như thế nào? Khi tôi sử dụng một bộ lọc với một đối tượng ng lặp đi lặp lại, tôi nhận được một lỗi đó là những gì được mong đợi dựa trên tài liệu Angular. – tonestrike

0

tôi đã hơn chút của một bộ lọc chung mà tôi đã sử dụng trong nhiều dự án đã:

  • đối tượng = đối tượng mà cần phải được lọc
  • lĩnh vực = lĩnh vực trong phạm vi đối tượng mà chúng ta sẽ lọc trên
  • lọc = giá trị của bộ lọc mà cần phải phù hợp với lĩnh vực này

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; 
    }; 
0

Mặc dù câu hỏi này là khá cũ , 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ỉ cần tái sử dụng bộ lọc góc ban đầu, nhưng minh bạch truyền bất kỳ đối tượng nào thành một 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

Các vấn đề liên quan