AngularJS ฟังก์ชั่นตัวกรองที่กำหนดเอง


91

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

ฉันพยายามใช้$filter('filter')(array, function)รูปแบบ แต่ฉันไม่รู้วิธีเข้าถึงองค์ประกอบแต่ละส่วนของอาร์เรย์ภายในฟังก์ชันของฉัน นี่คือตัวอย่างข้อมูลเพื่อแสดงสิ่งที่ฉันต้องการ

$filter('filter')(array, function() {
  return criteriaMatch(item, criteria);
});

จากนั้นcriteriaMatch()ฉันจะตรวจสอบว่าคุณสมบัติแต่ละรายการตรงกันหรือไม่

var criteriaMatch = function(item, criteria) {
  // go thro each individual property in the item and criteria
  // and check if they are equal
}

ฉันต้องทำสิ่งเหล่านี้ทั้งหมดในคอนโทรลเลอร์และรวบรวมรายชื่อรายการและตั้งค่าไว้ในขอบเขต ดังนั้นฉันจำเป็นต้องเข้าถึง$filter('filter')ด้วยวิธีนี้เท่านั้น ตัวอย่างทั้งหมดที่ฉันพบใน net จนถึงขณะนี้มีการค้นหาเกณฑ์แบบคงที่ภายในฟังก์ชันซึ่งไม่ผ่านวัตถุเกณฑ์และทดสอบกับแต่ละรายการในอาร์เรย์


3
ทำไมคุณถึงต้องมีตัวกรอง? โดยปกติแล้วตัวกรองจะใช้จากเทมเพลต คุณไม่สามารถมีฟังก์ชั่นธรรมดาในคอนโทรลเลอร์ของคุณได้หรือไม่หากคุณใช้งานจากที่นั่นเท่านั้น?
Ketan

แทนที่จะไปที่แต่ละองค์ประกอบของอาร์เรย์ด้วยตนเองฉันคิดว่าเราสามารถใช้ฟังก์ชัน $ filter ('filter') ของเชิงมุม (ซึ่งจะดูแลการวนซ้ำแต่ละองค์ประกอบหากเราระบุฟังก์ชันเพรดิเคต)
user2368436

คำตอบ:


174

คุณสามารถใช้งานได้ดังนี้: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview

เช่นเดียวกับที่คุณพบfilterยอมรับฟังก์ชันเพรดิเคตซึ่งรับรายการตามรายการจากอาร์เรย์ criteriaดังนั้นคุณก็ต้องสร้างฟังก์ชั่นกริยาขึ้นอยู่กับการได้รับ

ในตัวอย่างนี้เป็นฟังก์ชั่นซึ่งจะส่งกลับฟังก์ชันกริยาซึ่งตรงกับที่กำหนดcriteriaMatchcriteria

แม่แบบ:

<div ng-repeat="item in items | filter:criteriaMatch(criteria)">
  {{ item }}
</div>

ขอบเขต:

$scope.criteriaMatch = function( criteria ) {
  return function( item ) {
    return item.name === criteria.name;
  };
};

ฉันจะไม่ใช้ฟังก์ชัน criteriaMatch นี้จาก html .. ฉันจะเรียกมันจากภายในคอนโทรลเลอร์ได้อย่างไรว่าถูกต้องหรือไม่ $ filter ('filter') (อาร์เรย์ฟังก์ชัน () {return criteriaMatch (item, criteria);});
user2368436

6
หากคุณไม่ได้ใช้ในเทมเพลตของคุณการกำหนดตัวกรองจะไม่ทำให้คุณได้เปรียบใด ๆ คุณสามารถกำหนดฟังก์ชั่นจาวาสคริปต์ง่ายๆได้เพราะมันจะสั้นกว่านั้น คุณสามารถใช้พื้นเมืองfilterวิธีการในวัตถุอาร์เรย์:array.filter(function(item){return item.name === criteria.name;})
ติดสาย

ฉันมีฟังก์ชันจาวาสคริปต์ แค่อยากให้แน่ใจว่าเชิงมุมไม่มีวิธีที่ง่ายกว่านี้ .. ฉันจะยอมรับคำตอบของคุณ ขอบคุณ.
user2368436

2

นี่คือตัวอย่างของวิธีที่คุณใช้filterภายใน AngularJS JavaScript ของคุณ (แทนที่จะใช้ในองค์ประกอบ HTML)

ในตัวอย่างนี้เรามีอาร์เรย์ของระเบียนประเทศแต่ละรายการมีชื่อและรหัส ISO 3 อักขระ

เราต้องการเขียนฟังก์ชันซึ่งจะค้นหารายการนี้เพื่อหาระเบียนที่ตรงกับรหัสอักขระ 3 ตัวที่ระบุ

นี่คือวิธีที่เราทำได้โดยไม่ต้องใช้filter:

$scope.FindCountryByCode = function (CountryCode) {
    //  Search through an array of Country records for one containing a particular 3-character country-code.
    //  Returns either a record, or NULL, if the country couldn't be found.
    for (var i = 0; i < $scope.CountryList.length; i++) {
        if ($scope.CountryList[i].IsoAlpha3 == CountryCode) {
            return $scope.CountryList[i];
        };
    };
    return null;
};

ใช่ไม่มีอะไรผิดปกติกับที่

แต่นี่คือลักษณะของฟังก์ชันเดียวกันโดยใช้filter:

$scope.FindCountryByCode = function (CountryCode) {
    //  Search through an array of Country records for one containing a particular 3-character country-code.
    //  Returns either a record, or NULL, if the country couldn't be found.

    var matches = $scope.CountryList.filter(function (el) { return el.IsoAlpha3 == CountryCode; })

    //  If 'filter' didn't find any matching records, its result will be an array of 0 records.
    if (matches.length == 0)
        return null;

    //  Otherwise, it should've found just one matching record
    return matches[0];
};

สวยกว่ามาก

โปรดจำไว้ว่าfilterส่งคืนอาร์เรย์เป็นผลลัพธ์ (รายการของระเบียนที่ตรงกัน) ดังนั้นในตัวอย่างนี้เราจะต้องการส่งคืน 1 ระเบียนหรือค่า NULL

หวังว่านี่จะช่วยได้


0

นอกจากนี้หากคุณต้องการใช้ตัวกรองในคอนโทรลเลอร์ของคุณแบบเดียวกับที่คุณทำที่นี่:

<div ng-repeat="item in items | filter:criteriaMatch(criteria)">
  {{ item }}
</div>

คุณสามารถทำสิ่งต่างๆเช่น:

var filteredItems =  $scope.$eval('items | filter:filter:criteriaMatch(criteria)');

6
หรืออีกทางหนึ่งvar filteredItems = $filter('criteriaMatch')(items, criteria);
321zeno
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.