ฉันจะกรองอาร์เรย์ด้วย AngularJS และใช้คุณสมบัติของวัตถุที่กรองแล้วเป็นแอตทริบิวต์ ng-model ได้อย่างไร


122

ถ้าฉันมีอาร์เรย์ของออบเจ็กต์และต้องการผูกโมเดลเชิงมุมเข้ากับคุณสมบัติขององค์ประกอบใดองค์ประกอบหนึ่งตามตัวกรองฉันจะทำอย่างไร ฉันสามารถอธิบายได้ดีขึ้นด้วยตัวอย่างที่เป็นรูปธรรม:

HTML:

<!DOCTYPE html>
<html ng-app>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
        <meta charset=utf-8 />
        <title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
        <input ng-model="results.year">
        <input ng-model="results.subjects.title | filter:{grade:'C'}">
    </body>
</html>

ควบคุม:

function MyCtrl($scope) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
}

JSBin: http://jsbin.com/adisax/1/edit

ฉันต้องการที่จะกรองอินพุตที่สองกับเรื่องที่มีเกรด C ' แต่ฉันไม่ต้องการที่จะผูกรูปแบบไปยังชั้นประถมศึกษาปี ; ฉันต้องการผูกไว้กับชื่อวิชาที่มีเกรด 'C'

เป็นไปได้หรือไม่และถ้าเป็นเช่นนั้นจะทำอย่างไร?

คำตอบ:


127
<div ng-repeat="subject in results.subjects | filter:{grade:'C'}">
    <input ng-model="subject.title" />
</div>

1
ฉันเห็นว่าคุณกำลังไปทางไหน แต่ฉันไม่ต้องการทวนสัญญาณ คุณสมบัติที่ฉันจะกรองจริงๆคือคอลัมน์ประจำตัวดังนั้นจึงไม่ซ้ำกัน แต่ฉันเห็นว่านี่จะเป็นวิธีที่ถูกต้องในการแก้ปัญหาทั่วไป
Bernhard Hofmann

1
นี่คือการสอนสำหรับคนอิตาลี :) dev.stasbranger.com/post/77190983049/…
Silvio Troia

10
สิ่งนี้มีประโยชน์มากและสำหรับการผกผัน (ทุกอย่างนอกเหนือจาก C) สิ่งนี้จะใช้ได้:filter:{grade:'!'+'C'}
pulkitsinghal

2
คุณสามารถทำเช่นเดียวกันกับgrade array? ในกรณีของฉันฉันสร้างอาร์เรย์เกรดของฉันจากมุมมองต้นไม้และต้องการกรองผลลัพธ์สำหรับสิ่งที่อยู่ในอาร์เรย์
Juan Carlos Oropeza

157

คุณสามารถใช้ตัวกรอง "ตัวกรอง" ในคอนโทรลเลอร์เพื่อรับเกรด "C" ทั้งหมด การรับองค์ประกอบแรกของอาร์เรย์ผลลัพธ์จะทำให้คุณได้ชื่อเรื่องที่มีเกรด "C"

$scope.gradeC = $filter('filter')($scope.results.subjects, {grade: 'C'})[0];

http://jsbin.com/ewitun/1/edit

เช่นเดียวกับ ES6 ธรรมดา:

$scope.gradeC = $scope.results.subjects.filter((subject) => subject.grade === 'C')[0]

ฉันขอโทษฉันไม่ได้ทำตามตัวกรองที่สอง ('ตัวกรอง') คุณช่วยอธิบายเพิ่มเติมอีกหน่อยได้ไหม
Winnemucca

1
@stevek นั่นคือชื่อของตัวกรอง วิธีการกรอง () ให้ตัวกรอง เป็นเพียงตัวกรองที่เรียกว่าตัวกรองเพราะกรองอาร์เรย์ จะมีลักษณะเช่นนี้กับตัวกรองสกุลเงิน: $ filter ('currency') (amount, symbol, fractionSize) ตรวจสอบเอกสารที่นี่: docs.angularjs.org/api/ng/filter
Oliver

61

นี่คือ JSBin ที่แก้ไขพร้อมตัวอย่างการทำงาน:

http://jsbin.com/sezamuja/1/edit

นี่คือสิ่งที่ฉันทำกับตัวกรองในอินพุต:

<input ng-model="(results.subjects | filter:{grade:'C'})[0].title">

1
นี่คือข้อตกลงที่แท้จริง นี่คือพลัง นี่คือวิธีที่ ฉันไปกับสิ่งนี้และตอนนี้ฉันมีความสุข
user1576978

13

โปรดทราบว่าหากคุณใช้ตัวกรอง $ เช่นนี้:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});

และคุณบังเอิญมีเกรดอื่นสำหรับโอ้ฉันไม่รู้ CC หรือ AC หรือ C + หรือ CCC มันดึงพวกเขาเข้ามา คุณต้องผนวกข้อกำหนดสำหรับการจับคู่แบบตรงทั้งหมด:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'}, true);

สิ่งนี้ฆ่าฉันจริงๆเมื่อฉันดึงรายละเอียดค่าคอมมิชชั่นบางอย่างเช่นนี้

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}))[0];

ได้รับการเรียกหาข้อผิดพลาดเนื่องจากมีการดึงค่าคอมมิชชัน ID 56 แทนที่จะเป็น 6

การเพิ่มพลังจริงให้ตรงกันทุกประการ

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}, true))[0];

ถึงกระนั้นฉันก็ชอบสิ่งนี้มากกว่า (ฉันใช้ typescript ด้วยเหตุนี้ "Let" และ =>):

let obj = this.$filter('filter')(this.CommissionTypes, (item) =>{ 
             return item.commission_type_id === 6;
           })[0];

ฉันทำอย่างนั้นเพราะเมื่อถึงจุดหนึ่งบนท้องถนนฉันอาจต้องการรับข้อมูลเพิ่มเติมจากข้อมูลที่กรองแล้ว ฯลฯ ... การมีฟังก์ชั่นอยู่ตรงนั้นทำให้ฝากระโปรงเปิดออก


ฉันมีข้อผิดพลาดเดียวกันกับคุณขอบคุณสำหรับคำใบ้พร้อมพารามิเตอร์บูลีนที่สาม ก็ไม่รู้ตัว.
Georg Leber

12

หากคุณต้องการสร้างรายการผลลัพธ์แยกต่างหากในคอนโทรลเลอร์คุณสามารถใช้ตัวกรองได้

function MyCtrl($scope, filterFilter) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
  //create a filtered array of results 
  //with grade 'C' or subjects that have been failed
  $scope.failedSubjects = filterFilter($scope.results.subjects, {'grade':'C'});
}

จากนั้นคุณสามารถอ้างอิงล้มเหลวหัวเรื่องในลักษณะเดียวกับที่คุณอ้างอิงวัตถุผลลัพธ์

คุณสามารถอ่านเพิ่มเติมได้ที่นี่ https://docs.angularjs.org/guide/filter

เนื่องจากคำตอบนี้เชิงมุมได้อัปเดตเอกสารจึงแนะนำให้โทรไปที่ตัวกรอง

// update 
// eg: $filter('filter')(array, expression, comparator, anyPropertyKey);
// becomes
$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});

filterFilter คืออะไร? เป็นบริการหรือคำสั่งใด ๆ ? รหัสสำหรับ filterFilter อยู่ที่ไหน
Mou

เป็นบริการเชิงมุม ดูตัวอย่างแรกในลิงค์ด้านบน (ในไฟล์ scripts.js)
Kieran

แม้ว่าพวกเขาจะเปลี่ยนตัวกรองเอกสารแล้วตัวกรองก็ยังใช้งานได้ ..
Kieran

4

คุณยังสามารถใช้ฟังก์ชันกับ$filter('filter'):

var foo = $filter('filter')($scope.results.subjects, function (item) {
  return item.grade !== 'A';
});

4

หากคุณใช้ ES6 คุณสามารถ:

var sample = [1, 2, 3]

var result = sample.filter(elem => elem !== 2)

/* output */
[1, 3]

นอกจากนี้โปรดทราบว่าตัวกรองไม่อัปเดตอาร์เรย์ที่มีอยู่จะส่งคืนอาร์เรย์ที่กรองใหม่ทุกครั้ง


0

การใช้ตัวกรองเดียวกันใน HTML โดยมีหลายคอลัมน์เช่น

 variable = (array | filter : {Lookup1Id : subject.Lookup1Id, Lookup2Id : subject.Lookup2Id} : true)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.