การส่งผ่านอาร์กิวเมนต์ไปยังตัวกรอง angularjs


99

เป็นไปได้ไหมที่จะส่งอาร์กิวเมนต์ไปยังฟังก์ชันตัวกรองเพื่อให้คุณกรองด้วยชื่อใด ๆ

สิ่งที่ต้องการ

$scope.weDontLike = function(item, name) {
    console.log(arguments);
    return item.name != name;
};

คำตอบ:


223

จริงๆแล้วมีอีกวิธีหนึ่ง (อาจจะดีกว่า) ที่คุณสามารถใช้ตัวกรอง 'ตัวกรอง' เนทีฟของเชิงมุมและยังส่งอาร์กิวเมนต์ไปยังตัวกรองที่คุณกำหนดเองได้

พิจารณารหัสต่อไปนี้:

<div ng-repeat="group in groups">
    <li ng-repeat="friend in friends | filter:weDontLike(group.enemy.name)">
        <span>{{friend.name}}</span>
    <li>
</div>

เพื่อให้ทำงานได้คุณเพียงแค่กำหนดตัวกรองของคุณดังต่อไปนี้:

$scope.weDontLike = function(name) {
    return function(friend) {
        return friend.name != name;
    }
}

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

ฉันใช้เวลา 2 วันกว่าจะรู้ว่าคุณทำได้ยังไม่เห็นวิธีแก้ปัญหานี้ที่ไหนเลย

ชำระเงินขั้วย้อนกลับของตัวกรอง angular.jsเพื่อดูว่าคุณสามารถใช้สิ่งนี้สำหรับการดำเนินการอื่น ๆ ที่เป็นประโยชน์กับตัวกรองได้อย่างไร


ในกรณีที่ตัวกรองของคุณต้องการหลายอาร์กิวเมนต์โปรดดูที่ฉันจะเรียกตัวกรอง Angular.js ที่มีหลายอาร์กิวเมนต์ได้อย่างไร
nh2

วิธีนี้ยังแก้ปัญหาแปลก ๆ ที่ภายใน ng-repeat ฉันไม่สามารถส่งผ่านพารามิเตอร์ของตัวเองไปยังตัวกรองของฉันได้ ไม่ว่าฉันจะทำอะไรพวกเขาก็ยังคงกลับมาเป็นดัชนีและคอลเลกชันโดยรวม ด้วยการใช้วิธีการส่งคืนนี้ฉันสามารถส่งผ่านพารามิเตอร์ของฉันและยังคงโหลดองค์ประกอบดั้งเดิมได้การแก้ไขที่ดีเยี่ยม!
Dennis Smolek

คำตอบนี้ช่วยแก้ปัญหาของฉันที่ฉันไม่สามารถส่งตัวแปร $ ขอบเขตเป็นพารามิเตอร์ไปยังฟังก์ชันตัวกรองได้ ทางออกที่ดีที่สุด โหวตแล้ว!
valafar

ถ้าฉันสามารถโหวตได้มากกว่าหนึ่งครั้งฉันจะแน่ใจว่ามันเป็นคำตอบที่ได้รับการโหวตมากที่สุดในประวัติศาสตร์ของ SO สิ่งนี้ทำให้ฉันเบื่อหน่ายมาหลายปีแล้ว ... แล้วฉันก็พบคำตอบ (ตอนนี้อายุ 2 ขวบ) ... ขอบคุณมากอย่างไม่น่าเชื่อ
PKD

ยังมีประโยชน์ในปี 2019! ขอบคุณมาก.
ashilon

76

จากสิ่งที่ฉันเข้าใจคุณไม่สามารถส่งอาร์กิวเมนต์ไปยังฟังก์ชันตัวกรอง (เมื่อใช้ตัวกรอง "ตัวกรอง") สิ่งที่คุณต้องทำคือเขียนตัวกรองที่กำหนดเอง sth ดังนี้:

.filter('weDontLike', function(){

return function(items, name){

    var arrayToReturn = [];        
    for (var i=0; i<items.length; i++){
        if (items[i].name != name) {
            arrayToReturn.push(items[i]);
        }
    }

    return arrayToReturn;
};

นี่คือ jsFiddle ที่ใช้งานได้: http://jsfiddle.net/pkozlowski_opensource/myr4a/1/

ทางเลือกง่ายๆอื่น ๆ โดยไม่ต้องเขียนตัวกรองแบบกำหนดเองคือการจัดเก็บชื่อเพื่อกรองออกในขอบเขตแล้วเขียน:

$scope.weDontLike = function(item) {
  return item.name != $scope.name;
};

ขอบคุณครับท่านนายอำเภอ! การจัดเก็บชื่อในขอบเขตจะใช้ไม่ได้เช่นเดียวกับฉันมีสามรายการจากข้อมูลเดียวกันในหน้าเดียวกันฉันจะกรองด้วยสถานะ (หรือชื่อ) ที่แตกต่างกัน
จำแลง

มีการตั้งค่า 'Adam' (หมายถึง JSFiddle ของคุณ) แบบไดนามิกหรือไม่? ดูเหมือนเป็นไปไม่ได้ (และฉันเดาว่าเป็นไปตามวัตถุประสงค์) ที่จะรวม ngModel และตัวกรองแบบกำหนดเองใน Angular ...
Rolf

เป็นไปได้ไหมที่จะเรียงลำดับพารามิเตอร์ของตัวกรองใหม่ ตัวอย่างเช่นส่งรายการไปยังพารามิเตอร์ที่สองของตัวกรอง?
Pooya

เป็นที่น่าสังเกตว่าในตัวอย่างนี้มาร์กอัปคือ {{items | weDontLike: 'thenameyoudontlike'}} ... ตอนนี้คุณต้องไปที่ซอเพื่อรับสิ่งนั้น นอกจากนี้ที่น่าสังเกตว่าคุณสามารถส่งพารามิเตอร์หลายตัวไปยังตัวกรองที่กำหนดเองได้ {{items | weDontLike: 'thename': ['I am', 'an array']: 'and so on'}} คุณเพียงแค่เพิ่มอาร์กิวเมนต์ให้กับตัวกรองที่กำหนดเองของคุณเพื่อให้สามารถเข้าถึงได้
Benjamin Conant

62

จริงๆแล้วคุณสามารถส่งผ่านพารามิเตอร์ ( http://docs.angularjs.org/api/ng.filter:filter ) และไม่จำเป็นต้องมีฟังก์ชันที่กำหนดเองสำหรับสิ่งนี้ หากคุณเขียน HTML ใหม่ตามด้านล่างจะใช้งานได้:

<div ng:app>
 <div ng-controller="HelloCntl">
 <ul>
    <li ng-repeat="friend in friends | filter:{name:'!Adam'}">
        <span>{{friend.name}}</span>
        <span>{{friend.phone}}</span>
    </li>
 </ul>
 </div>
</div>

http://jsfiddle.net/ZfGx4/59/


8
ใช่. หมายเหตุด้านข้าง - ถ้าใครชื่อ '! Adam' คุณจะเรียกเขาว่า {name: '!! Adam'}
honzajde

5
คุณสามารถส่งอาร์เรย์ที่นี่ได้เช่นกันfilter:['Adam', 'john']
iConnor

6
ลิงค์ jsfiddle เสีย
Seregwethrin

4
! อดัมเป็นชื่อที่แย่ที่สุดเท่าที่เคยมีมา
Ben Wheeler

6
Not-Not-Adam แย่กว่าอย่างเห็นได้ชัด
ทวิป

30

คุณสามารถทำเช่นนี้ในเทมเพลต

<span ng-cloak>{{amount |firstFiler:'firstArgument':'secondArgument' }}</span>

ในตัวกรอง

angular.module("app")
.filter("firstFiler",function(){

    console.log("filter loads");
    return function(items, firstArgument,secondArgument){
        console.log("item is ",items); // it is value upon which you have to filter
        console.log("firstArgument is ",firstArgument);
        console.log("secondArgument ",secondArgument);

        return "hello";
    }
    });

นี่คือคำตอบที่ดีที่สุด ทำงานกับวัตถุแบบไดนามิก นี่ควรเป็นคำตอบที่ได้รับการยอมรับ
abelabbesnabi

2

การขยายคำตอบของ pkozlowski.opensourceและการใช้array'sวิธีการกรองในตัวจาวาสคริปต์โซลูชันที่กำหนดไว้ล่วงหน้าอาจเป็นดังนี้:

.filter('weDontLike', function(){
    return function(items, name){
        return items.filter(function(item) {
            return item.name != name;
        });
    };
});

นี่คือ jsfiddle การเชื่อมโยง

เพิ่มเติมเกี่ยวกับตัวกรองอาร์เรย์ที่นี่


1

คุณสามารถส่งผ่านหลายอาร์กิวเมนต์ไปยังตัวกรองเชิงมุม!

การกำหนดแอพเชิงมุมของฉันและและตัวแปรระดับแอพ -

var app = angular.module('filterApp',[]);
app.value('test_obj', {'TEST' : 'test be check se'});

ตัวกรองของคุณจะเป็นดังนี้: -

app.filter('testFilter', [ 'test_obj', function(test_obj) {
    function test_filter_function(key, dynamic_data) {
      if(dynamic_data){
        var temp = test_obj[key]; 
        for(var property in dynamic_data){
            temp = temp.replace(property, dynamic_data[property]);
        }
        return temp;
      }
      else{
        return test_obj[key] || key;
      }

    }
    test_filter_function.$stateful = true;
    return test_filter_function;
  }]);

และจาก HTML คุณจะส่งข้อมูลเช่น: -

<span ng-bind="'TEST' | testFilter: { 'be': val, 'se': value2 }"></span>

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

นอกจากนี้คุณสามารถส่งจำนวนอาร์กิวเมนต์แบบไดนามิกเพื่อกรองในกรณีนี้คุณต้องใช้อาร์กิวเมนต์เพื่อรับอาร์กิวเมนต์เหล่านั้น

สำหรับการสาธิตที่ใช้งานได้ให้ไปที่นี่ - ส่งผ่านหลายอาร์กิวเมนต์ไปยังตัวกรองเชิงมุม


0

คุณสามารถใช้ไฟล์ | filter:yourFunction:arg

<div ng-repeat="group in groups | filter:weDontLike:group">...</div>

และใน js

$scope.weDontLike = function(group) {
//here your condition/criteria
return !!group 
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.