angular ng-repeat ข้ามรายการหากตรงกับนิพจน์


91

ฉันกำลังมองหาวิธีที่จะบอกพื้นเชิงมุมที่จะข้ามรายการใน ng ซ้ำว่าตรงกับการแสดงออกโดยทั่วไปcontinue;

ในตัวควบคุม:

$scope.players = [{
    name_key:'FirstPerson', first_name:'First', last_name:'Person'
}, {
    name_key:'SecondPerson', first_name:'Second', last_name:'Person'
}]

name_key='FirstPerson'ตอนนี้ในแม่แบบของฉันฉันต้องการที่จะแสดงให้ทุกคนที่ไม่ตรงกับ ฉันคิดว่ามันต้องเป็นตัวกรองดังนั้นฉันจึงตั้งค่า Plunkr เพื่อเล่นกับมัน แต่ไม่มีโชคเลย Plunkr พยายาม


ฉันพยายามที่จะเข้าใจ: คุณต้องการแสดงรายการทั้งหมด แต่ชี้ว่าใครตรงและใครไม่ใช่ หรือแค่กรอง?
Maxim Shoustin

คำตอบ:


144

ตามที่@Maxim Shoustinแนะนำวิธีที่ดีที่สุดในการบรรลุสิ่งที่คุณต้องการคือการใช้ตัวกรองแบบกำหนดเอง
แต่มีวิธีอื่นอีกวิธีหนึ่งคือการใช้ng-ifคำสั่งกับองค์ประกอบเดียวกันคือคุณวางng-repeatคำสั่ง (เช่นกันนี่คือplunker ):

<ul>
    <li ng-repeat="player in players" ng-if="player.name_key!='FirstPerson'"></li>
</ul>

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

  <li 
      ng-repeat="player in players" 
      ng-if="app.loggedIn && player.name != user.name"
  ></li>

อัปเดต
ตามที่ระบุไว้นี่เป็นหนึ่งในวิธีแก้ปัญหาประเภทนี้และอาจตรงกับความต้องการของคุณ
ตามที่ระบุไว้ในความคิดเห็นng-ifเป็นคำสั่งซึ่งจริงๆแล้วหมายความว่าอาจทำสิ่งต่างๆในเบื้องหลังมากกว่าที่คุณคาดหวัง
ตัวอย่างเช่นng-if สร้างขอบเขตใหม่จากระดับบนสุด :

ขอบเขตที่สร้างขึ้นภายใน ngIf สืบทอดมาจากขอบเขตพาเรนต์โดยใช้การสืบทอดโปรโตไทป์

โดยปกติจะไม่ส่งผลกระทบต่อพฤติกรรมปกติ แต่เพื่อป้องกันกรณีที่ไม่คาดคิดคุณควรคำนึงถึงสิ่งนี้ก่อนที่จะดำเนินการ


นี่คือสิ่งที่ฉันกำลังมองหารู้ดีว่ามันต้องมีวิธีที่สั้นและไพเราะโดยไม่ต้องใช้ตัวกรองแบบกำหนดเอง ขอบคุณ!
aron.duby

หมายเหตุ: มีขอบเขตพฤติกรรมบางอย่างของ ng-if ที่อาจเป็นเรื่องยุ่งยาก ฉันลองใช้วิธีนี้และทำให้เกิดปัญหาที่อื่น กล่าวคือฉันมีคำสั่ง "ผู้เฝ้าดู" ที่ถ่ายทอดเหตุการณ์เมื่อทวนสัญญาณเสร็จสิ้น หลังจากเพิ่ม ng-if ลงใน repeater นี้จะไม่ยิงเหตุการณ์นั้นอีกต่อไป ตัวกรองแบบกำหนดเองอาจเป็นวิธีที่สะอาดที่สุด
claywhipkey

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

43

ฉันรู้ว่านี่เป็นรุ่นเก่า แต่ในกรณีที่มีคนมองหาวิธีแก้ปัญหาอื่นที่เป็นไปได้นี่เป็นอีกวิธีหนึ่งในการแก้ปัญหานี้ - ใช้ฟังก์ชันตัวกรองมาตรฐาน:

วัตถุ:สามารถใช้วัตถุรูปแบบเพื่อกรองคุณสมบัติเฉพาะของวัตถุที่อยู่ในอาร์เรย์ ตัวอย่างเช่นเพรดิเคต {name: "M", phone: "1"} จะส่งคืนอาร์เรย์ของรายการที่มีชื่อคุณสมบัติประกอบด้วย "M" และโทรศัพท์คุณสมบัติที่มี "1" ... เพรดิเคตสามารถลบล้างได้โดยนำหน้าสตริงด้วย! ตัวอย่างเช่นเพรดิเคต {name: "! M"} จะส่งคืนอาร์เรย์ของรายการที่มีชื่อคุณสมบัติที่ไม่มี "M"

ดังนั้นสำหรับตัวอย่าง TS สิ่งนี้ควรทำ:

<ul>
    <li ng-repeat="player in players | filter: { name_key: '!FirstPerson' }"></li>
</ul>

ไม่จำเป็นต้องเขียนฟิลเตอร์ที่กำหนดเองไม่จำเป็นต้องใช้ng-ifกับขอบเขตใหม่


ง่ายตรงประเด็น ไม่มีการสร้างตัวกรองที่กำหนดเองหรือขอบเขตใหม่ตามที่ผู้เขียนระบุไว้ เหมาะสำหรับการข้ามค่าเดียวในรายการ
mbokil

ฉันคิดว่าคุณต้องละเว้น "player" จาก "player.name_key" - ดังนั้นจึงเป็นเพียง "{name_key: '! FirstPerson'}" ในตัวอย่างด้านบน
smithml

ฉันไม่สามารถทำให้ Angular เล่นได้ดีกับคีย์เปล่า ๆ มีเคล็ดลับบางอย่างสำหรับการใช้ตัวกรองในตัวเพื่อให้เทียบเท่ากับplayer in players | filter: { name_key: '' }? ที่สั่งโดยเฉพาะอย่างยิ่งจะไม่ตรงกับผู้เล่นที่ไม่มี / name_keyที่ว่างเปล่า การผกผันที่name_key: '!'มีไว้เพื่อเลือกผู้เล่นที่ไม่ว่างเปล่าname_keyจะไม่ทำงาน
Eric L.

คุณสามารถตรวจสอบนี้คำตอบ
Ilya Luzyanin

4
ระวังว่าสิ่งนี้ใช้ได้กับอาร์เรย์เท่านั้นไม่ใช่กับคุณสมบัติของวัตถุในกรณีเช่นng-repeat="(key, val) in player"
David Diez

19

คุณสามารถใช้กำหนดเองng-repeatกรองเมื่อคุณใช้ สิ่งที่ต้องการ:

 data-ng-repeat="player in players |  myfilter:search.name

myfilter.js:

app.filter('myfilter', function() {


   return function( items, name) {
    var filtered = [];

    angular.forEach(items, function(item) {

      if(name == undefined || name == ''){
        filtered.push(item);
        }

      /* only if you want start With*/
      // else if(item.name_key.substring(0, name.length) !== name){
      //   filtered.push(item);
      // }

      /* if you want contains*/
      // else if(item.name_key.indexOf(name) < 0 ){
      //   filtered.push(item);
      // }

       /* if you want match full name*/
       else if(item.name_key !== name ){
        filtered.push(item);
      }
    });

    return filtered;
  };
});

การสาธิต Plunker


ขอบคุณสำหรับผลงานที่คุณนำมาฝาก ถูกต้องแน่นอน แต่ฉันลงเอยด้วยความง่ายของคำตอบ @ gion_13 ในรหัสดังนั้นฉันจึงคิดว่าฉันควรทำเครื่องหมายเขาเป็นคำตอบที่ยอมรับ
aron.duby
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.