NgFor ไม่อัปเดตข้อมูลด้วย Pipe ใน Angular2


114

ในสถานการณ์นี้ฉันกำลังแสดงรายชื่อนักเรียน (อาร์เรย์) ในมุมมองด้วยngFor:

<li *ngFor="#student of students">{{student.name}}</li>

มันยอดเยี่ยมมากที่มีการอัปเดตทุกครั้งที่ฉันเพิ่มนักเรียนคนอื่นในรายการ

แต่เมื่อฉันให้มันเป็นpipeไปfilterตามชื่อนักเรียน

<li *ngFor="#student of students | sortByName:queryElem.value ">{{student.name}}</li>

จะไม่อัปเดตรายการจนกว่าฉันจะพิมพ์บางสิ่งในฟิลด์ชื่อนักเรียนที่กรอง

นี่คือการเชื่อมโยงไปยังplnkr

Hello_world.html

<h1>Students:</h1>
<label for="newStudentName"></label>
<input type="text" name="newStudentName" placeholder="newStudentName" #newStudentElem>
<button (click)="addNewStudent(newStudentElem.value)">Add New Student</button>
<br>
<input type="text" placeholder="Search" #queryElem (keyup)="0">
<ul>
    <li *ngFor="#student of students | sortByName:queryElem.value ">{{student.name}}</li>
</ul>

sort_by_name_pipe.ts

import {Pipe} from 'angular2/core';

@Pipe({
    name: 'sortByName'
})
export class SortByNamePipe {

    transform(value, [queryString]) {
        // console.log(value, queryString);
        return value.filter((student) => new RegExp(queryString).test(student.name))
        // return value;
    }
}


14
เพิ่มpure:falseในท่อของคุณและchangeDetection: ChangeDetectionStrategy.OnPushในส่วนประกอบของคุณ
Eric Martinez

2
ขอบคุณ @EricMartinez มันได้ผล. แต่ช่วยอธิบายนิดนึงได้ไหม?
Chu Son

2
นอกจากนี้ฉันขอแนะนำว่าอย่าใช้.test()ในฟังก์ชันตัวกรองของคุณ เนื่องจากหากผู้ใช้ป้อนสตริงที่มีอักขระที่มีความหมายพิเศษเช่น: *หรือ+อื่น ๆ รหัสของคุณจะพัง ฉันคิดว่าคุณควรใช้.includes()หรือหลีกเลี่ยงสตริงการสืบค้นด้วยฟังก์ชันที่กำหนดเอง
Eggy

6
การเพิ่มpure:falseและทำให้ไปป์ของคุณมีสถานะจะช่วยแก้ปัญหาได้ ไม่จำเป็นต้องแก้ไข ChangeDetectionStrategy
pixelbits

2
สำหรับใครก็ตามที่อ่านสิ่งนี้เอกสารสำหรับ Angular Pipes นั้นดีขึ้นมากและกล่าวถึงสิ่งเดียวกันหลายอย่างที่กล่าวถึงที่นี่ ลองดูสิ
0xcaff

คำตอบ:


154

เพื่อให้เข้าใจปัญหาอย่างถ่องแท้และแนวทางแก้ไขที่เป็นไปได้เราต้องหารือเกี่ยวกับการตรวจจับการเปลี่ยนแปลงเชิงมุม - สำหรับท่อและส่วนประกอบ

การตรวจจับการเปลี่ยนท่อ

ท่อไร้สัญชาติ / บริสุทธิ์

โดยค่าเริ่มต้นไปป์จะไร้สัญชาติ / บริสุทธิ์ ท่อไร้สัญชาติ / บริสุทธิ์เพียงแค่แปลงข้อมูลอินพุตเป็นข้อมูลเอาต์พุต พวกเขาจำอะไรไม่ได้ดังนั้นจึงไม่มีคุณสมบัติใด ๆ - เป็นเพียงtransform()วิธีการ Angular จึงสามารถปรับการรักษาไปป์ไร้สัญชาติ / บริสุทธิ์ได้อย่างเหมาะสมที่สุด: หากปัจจัยการผลิตไม่เปลี่ยนแปลงท่อก็ไม่จำเป็นต้องดำเนินการในระหว่างรอบการตรวจจับการเปลี่ยนแปลง สำหรับท่อเช่น{{power | exponentialStrength: factor}}, powerและfactorเป็นปัจจัยการผลิต

สำหรับคำถามนี้"#student of students | sortByName:queryElem.value", studentsและqueryElem.valueเป็นปัจจัยการผลิตและท่อsortByNameเป็นไร้สัญชาติ / บริสุทธิ์ studentsคืออาร์เรย์ (การอ้างอิง)

  • เมื่อมีการเพิ่มนักเรียนการอ้างอิงอาร์เรย์จะไม่เปลี่ยนแปลง - studentsไม่เปลี่ยนแปลงดังนั้นจึงไม่มีการดำเนินการไปป์ไร้สัญชาติ / บริสุทธิ์
  • เมื่อมีการพิมพ์บางสิ่งลงในอินพุตตัวกรองqueryElem.valueจะมีการเปลี่ยนแปลงดังนั้นจึงมีการดำเนินการไปป์ไร้สัญชาติ / บริสุทธิ์

วิธีหนึ่งในการแก้ไขปัญหาอาร์เรย์คือการเปลี่ยนการอ้างอิงอาร์เรย์ทุกครั้งที่มีการเพิ่มนักเรียนกล่าวคือสร้างอาร์เรย์ใหม่ทุกครั้งที่มีการเพิ่มนักเรียน เราสามารถทำได้ด้วยconcat():

this.students = this.students.concat([{name: studentName}]);

แม้ว่าวิธีนี้จะได้ผล แต่addNewStudent()วิธีการของเราก็ไม่ควรนำมาใช้ด้วยวิธีใดวิธีหนึ่งเพียงเพราะเราใช้ไปป์ เราต้องการใช้push()เพื่อเพิ่มในอาร์เรย์ของเรา

ท่อสถานะ

ท่อที่มีสถานะมีสถานะ - โดยปกติจะมีคุณสมบัติไม่ใช่แค่transform()วิธีการ พวกเขาอาจต้องได้รับการประเมินแม้ว่าปัจจัยการผลิตจะไม่เปลี่ยนแปลงก็ตาม เมื่อเราระบุว่าไปป์มีสถานะ / ไม่บริสุทธิ์ - pure: false- เมื่อใดก็ตามที่ระบบตรวจจับการเปลี่ยนแปลงของ Angular ตรวจสอบส่วนประกอบสำหรับการเปลี่ยนแปลงและส่วนประกอบนั้นใช้ไปป์แบบ stateful ระบบจะตรวจสอบเอาต์พุตของไปป์ว่าอินพุตมีการเปลี่ยนแปลงหรือไม่

สิ่งนี้ดูเหมือนสิ่งที่เราต้องการแม้ว่าจะมีประสิทธิภาพน้อยกว่าเนื่องจากเราต้องการให้ไพพ์ทำงานแม้ว่าการstudentsอ้างอิงจะไม่เปลี่ยนแปลงก็ตาม หากเราทำให้ไปป์มีสถานะเป็นปกติเราจะได้รับข้อผิดพลาด:

EXCEPTION: Expression 'students | sortByName:queryElem.value  in HelloWorld@7:6' 
has changed after it was checked. Previous value: '[object Object],[object Object]'. 
Current value: '[object Object],[object Object]' in [students | sortByName:queryElem.value

ตามคำตอบของ @drewmoore "ข้อผิดพลาดนี้เกิดขึ้นในโหมด dev เท่านั้น (ซึ่งเปิดใช้งานโดยค่าเริ่มต้นเป็นเบต้า -0) หากคุณโทรหาenableProdMode()เมื่อบูตเครื่องแอปข้อผิดพลาดจะไม่เกิดขึ้น" เอกสารสำหรับApplicationRef.tick()รัฐ:

ในโหมดการพัฒนาขีด () ยังดำเนินการตรวจจับการเปลี่ยนแปลงรอบที่สองเพื่อให้แน่ใจว่าไม่มีการตรวจพบการเปลี่ยนแปลงเพิ่มเติม หากมีการเปลี่ยนแปลงเพิ่มเติมในรอบที่สองนี้การเชื่อมโยงในแอปจะมีผลข้างเคียงที่ไม่สามารถแก้ไขได้ในการตรวจจับการเปลี่ยนแปลงครั้งเดียว ในกรณีนี้ Angular จะแสดงข้อผิดพลาดเนื่องจากแอปพลิเคชัน Angular สามารถมีการตรวจจับการเปลี่ยนแปลงได้เพียงครั้งเดียวในระหว่างที่การตรวจจับการเปลี่ยนแปลงทั้งหมดจะต้องเสร็จสมบูรณ์

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

อย่างไรก็ตามเราไม่สามารถพัฒนาได้จริง ๆ เมื่อเกิดข้อผิดพลาดนี้ดังนั้นวิธีแก้ปัญหาอย่างหนึ่งคือการเพิ่มคุณสมบัติอาร์เรย์ (เช่นสถานะ) ให้กับการนำไปใช้งานไปป์และส่งคืนอาร์เรย์นั้นเสมอ ดูคำตอบของ @ pixelbits สำหรับโซลูชันนี้

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

การตรวจจับการเปลี่ยนแปลงส่วนประกอบ

ตามค่าเริ่มต้นในทุกเหตุการณ์ของเบราว์เซอร์การตรวจจับการเปลี่ยนแปลงเชิงมุมจะตรวจสอบทุกองค์ประกอบเพื่อดูว่ามีการเปลี่ยนแปลงหรือไม่ - อินพุตและเทมเพลต (และอาจเป็นอย่างอื่น?)

ถ้าเรารู้ว่าส่วนประกอบขึ้นอยู่กับคุณสมบัติการป้อนข้อมูล (และเหตุการณ์เทมเพลต) เท่านั้นและคุณสมบัติการป้อนข้อมูลไม่เปลี่ยนรูปเราสามารถใช้onPushกลยุทธ์การตรวจจับการเปลี่ยนแปลงที่มีประสิทธิภาพมากขึ้นได้ ด้วยกลยุทธ์นี้แทนที่จะตรวจสอบทุกเหตุการณ์ของเบราว์เซอร์คอมโพเนนต์จะถูกตรวจสอบเฉพาะเมื่ออินพุตเปลี่ยนไปและเมื่อเหตุการณ์ของเทมเพลตทริกเกอร์ และเห็นได้ชัดว่าเราไม่ได้รับExpression ... has changed after it was checkedข้อผิดพลาดจากการตั้งค่านี้ เนื่องจากonPushจะไม่มีการตรวจสอบส่วนประกอบอีกจนกว่าจะมีการ "ทำเครื่องหมาย" ( ChangeDetectorRef.markForCheck()) อีกครั้ง ดังนั้นการเชื่อมเทมเพลตและเอาต์พุตไปป์ stateful จึงถูกดำเนินการ / ประเมินเพียงครั้งเดียว ท่อไร้สัญชาติ / บริสุทธิ์จะยังคงไม่ดำเนินการเว้นแต่ปัจจัยการผลิตจะเปลี่ยนไป ดังนั้นเรายังคงต้องการท่อที่มีสถานะตรงนี้

นี่คือวิธีแก้ปัญหาที่ @EricMartinez แนะนำ: ไปป์ stateful พร้อมonPushการตรวจจับการเปลี่ยนแปลง ดูคำตอบของ @ caffinatedmonkey สำหรับโซลูชันนี้

โปรดทราบว่าด้วยวิธีนี้transform()วิธีนี้ไม่จำเป็นต้องส่งคืนอาร์เรย์เดียวกันทุกครั้ง ฉันคิดว่ามันแปลกไปหน่อย: ไปป์ที่มีสถานะไม่มีสถานะ ลองคิดดูเพิ่มเติม ... ท่อสถานะน่าจะส่งคืนอาร์เรย์เดียวกันเสมอ มิฉะนั้นจะสามารถใช้ได้เฉพาะกับonPushส่วนประกอบในโหมด dev


หลังจากนั้นฉันคิดว่าฉันชอบการผสมผสานระหว่างคำตอบของ @ Eric และ @ pixelbits: ไปป์ stateful ที่ส่งคืนการอ้างอิงอาร์เรย์เดียวกันพร้อมonPushการตรวจจับการเปลี่ยนแปลงหากส่วนประกอบอนุญาต เนื่องจากท่อ stateful onPushกลับอ้างอิงอาร์เรย์เดียวกันท่อยังสามารถใช้กับชิ้นส่วนที่ไม่ได้รับการกำหนดค่าด้วย

Plunker

สิ่งนี้อาจจะกลายเป็นสำนวน Angular 2: ถ้าอาร์เรย์ป้อนไปป์และอาร์เรย์อาจเปลี่ยนแปลง (รายการในอาร์เรย์ที่ไม่ใช่การอ้างอิงอาร์เรย์) เราจำเป็นต้องใช้ไปป์ที่มีสถานะ


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

@MartinNowak ถ้าคุณถามว่าอาร์เรย์เป็น Observable หรือไม่และท่อก็ไร้สัญชาติ ... ฉันไม่รู้ฉันยังไม่ได้ลอง
Mark Rajcok

อีกวิธีหนึ่งคือไปป์บริสุทธิ์ที่อาร์เรย์เอาต์พุตกำลังติดตามการเปลี่ยนแปลงในอาร์เรย์อินพุตด้วยตัวฟังเหตุการณ์
Tuupertunut

ฉันเพิ่งแยก Plunker ของคุณและใช้ได้กับฉันโดยไม่มีonPushการตรวจจับการเปลี่ยนแปลงplnkr.co/edit/gRl0Pt9oBO6038kCXZPk?p=preview
Dan

28

ในฐานะที่เป็นเอริคมาร์ติชี้ให้เห็นในความคิดเห็นที่เพิ่มpure: falseที่คุณPipeมัณฑนากรและchangeDetection: ChangeDetectionStrategy.OnPushที่คุณComponentมัณฑนากรจะแก้ไขปัญหาของคุณ นี่คือพนักงานที่ทำงาน เปลี่ยนไปใช้ChangeDetectionStrategy.Alwaysงานได้เช่นกัน นี่คือเหตุผล

ตามคู่มือ angular2 บนท่อ :

ท่อไร้สัญชาติโดยค่าเริ่มต้น เราต้องประกาศท่อที่จะ stateful โดยการตั้งค่าpureคุณสมบัติของมัณฑนากรที่จะ@Pipe falseการตั้งค่านี้จะบอกให้ระบบตรวจจับการเปลี่ยนแปลงของ Angular ตรวจสอบเอาต์พุตของไปป์นี้ในแต่ละรอบว่าอินพุตมีการเปลี่ยนแปลงหรือไม่

สำหรับChangeDetectionStrategyค่าเริ่มต้นการเชื่อมโยงทั้งหมดจะถูกตรวจสอบทุกๆรอบ เมื่อมีการpure: falseเพิ่มท่อฉันเชื่อว่าวิธีการตรวจจับการเปลี่ยนแปลงเปลี่ยนจากCheckAlwaysเป็นCheckOnceเป็นด้วยเหตุผลด้านประสิทธิภาพ ด้วยOnPushการเชื่อมโยงสำหรับคอมโพเนนต์จะถูกตรวจสอบเมื่อคุณสมบัติอินพุตเปลี่ยนแปลงหรือเมื่อเหตุการณ์ถูกทริกเกอร์เท่านั้น สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเครื่องมือตรวจจับการเปลี่ยนแปลงส่วนสำคัญangular2โปรดดูลิงก์ต่อไปนี้:


"เมื่อมีการpure: falseเพิ่มไปป์ฉันเชื่อว่าวิธีการตรวจจับการเปลี่ยนแปลงเปลี่ยนจาก CheckAlways เป็น CheckOnce" ซึ่งไม่เห็นด้วยกับสิ่งที่คุณยกมาจากเอกสาร ความเข้าใจของฉันมีดังนี้: อินพุตของท่อไร้สถานะจะถูกตรวจสอบทุกรอบตามค่าเริ่มต้น หากมีการเปลี่ยนแปลงtransform()เมธอดของท่อจะถูกเรียกให้ (re) สร้างเอาต์พุต transform()เมธอดของ stateful ไปป์เรียกว่าทุกๆรอบและเอาต์พุตจะถูกตรวจสอบการเปลี่ยนแปลง ดูstackoverflow.com/a/34477111/215945ด้วย
Mark Rajcok

@MarkRajcok อ๊ะคุณพูดถูก แต่ถ้าเป็นเช่นนั้นทำไมการเปลี่ยนกลยุทธ์การตรวจจับการเปลี่ยนแปลงจึงได้ผล
0xcaff

1
คำถามที่ดี ดูเหมือนว่าเมื่อเปลี่ยนกลยุทธ์การตรวจจับการเปลี่ยนแปลงเป็นOnPush(กล่าวคือส่วนประกอบถูกทำเครื่องหมายว่า "ไม่เปลี่ยนรูป") เอาต์พุตไปป์ stateful ไม่จำเป็นต้อง "คงตัว" - กล่าวคือดูเหมือนว่าtransform()วิธีการนี้จะทำงานเพียงครั้งเดียว (อาจทั้งหมด การตรวจจับการเปลี่ยนแปลงสำหรับส่วนประกอบจะรันเพียงครั้งเดียว) ตรงกันข้ามกับคำตอบของ @ pixelbits โดยที่transform()เมธอดนี้ถูกเรียกหลาย ๆ ครั้งและต้องทำให้เสถียร (ตามคำตอบอื่นของ pixelbits ) ดังนั้นจึงจำเป็นต้องใช้การอ้างอิงอาร์เรย์เดียวกัน
Mark Rajcok

@MarkRajcok ถ้าสิ่งที่คุณพูดถูกต้องในแง่ของประสิทธิภาพนี่น่าจะเป็นวิธีที่ดีกว่าในกรณีการใช้งานนี้เพราะtransformจะเรียกเฉพาะเมื่อข้อมูลใหม่ถูกผลักแทนที่จะเป็นหลาย ๆ ครั้งจนกว่าเอาต์พุตจะคงที่ใช่ไหม
0xcaff

1
อาจดูคำตอบที่ยืดยาวของฉัน ฉันหวังว่าจะมีเอกสารเพิ่มเติมเกี่ยวกับการตรวจจับการเปลี่ยนแปลงใน Angular 2
Mark Rajcok

22

Demo Plunkr

คุณไม่จำเป็นต้องเปลี่ยน ChangeDetectionStrategy การใช้งาน Pipe แบบ stateful ก็เพียงพอที่จะทำให้ทุกอย่างทำงานได้

นี่คือไปป์ stateful (ไม่มีการเปลี่ยนแปลงอื่น ๆ ):

@Pipe({
  name: 'sortByName',
  pure: false
})
export class SortByNamePipe {
  tmp = [];
  transform (value, [queryString]) {
    this.tmp.length = 0;
    // console.log(value, queryString);
    var arr = value.filter((student)=>new RegExp(queryString).test(student.name));
    for (var i =0; i < arr.length; ++i) {
        this.tmp.push(arr[i]);
     }

    return this.tmp;
  }
}

ฉันได้รับข้อผิดพลาดนี้โดยไม่ต้องแก้ไข changeDectection เป็น onPush: [ plnkr.co/edit/j1VUdgJxYr6yx8WgzCId?p=preview](Plnkr) Expression 'students | sortByName:queryElem.value in HelloWorld@7:6' has changed after it was checked. Previous value: '[object Object],[object Object],[object Object]'. Current value: '[object Object],[object Object],[object Object]' in [students | sortByName:queryElem.value in HelloWorld@7:6]
Chu Son

1
คุณสามารถยกตัวอย่างได้ไหมว่าทำไมคุณถึงต้องเก็บค่าไว้ในตัวแปรโลคัลใน SortByNamePipe แล้วส่งคืนในฟังก์ชัน transform @pixelbits ฉันยังสังเกตเห็นว่า Angular cycle ผ่านฟังก์ชั่นการแปลงสองครั้งโดยมี changeDetetion OnPush และ 4 ครั้งหากไม่มีมัน
Chu Son

@ChuSon คุณอาจกำลังดูบันทึกจากเวอร์ชันก่อนหน้า แทนที่จะส่งคืนอาร์เรย์ของค่าเรากำลังส่งคืนการอ้างอิงไปยังอาร์เรย์ของค่าซึ่งสามารถตรวจพบการเปลี่ยนแปลงได้ Pixelbits คำตอบของคุณมีเหตุผลมากขึ้น
0xcaff

เพื่อประโยชน์ของผู้อ่านคนอื่น ๆ เกี่ยวกับข้อผิดพลาด ChuSon ที่กล่าวถึงข้างต้นในความคิดเห็นและความจำเป็นในการใช้ตัวแปรท้องถิ่นคำถามอื่นถูกสร้างขึ้นและตอบโดย pixelbits
Mark Rajcok

19

จากเอกสารเชิงมุม

ท่อบริสุทธิ์และไม่บริสุทธิ์

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

@Pipe({ name: 'flyingHeroesImpure', pure: false })

ก่อนที่จะทำเช่นนั้นให้เข้าใจความแตกต่างระหว่างบริสุทธิ์และไม่บริสุทธิ์โดยเริ่มจากท่อบริสุทธิ์

ท่อบริสุทธิ์เชิงมุมจะดำเนินการท่อบริสุทธิ์เฉพาะเมื่อตรวจพบการเปลี่ยนแปลงที่แท้จริงของค่าอินพุต การเปลี่ยนแปลงที่แท้จริงคือการเปลี่ยนแปลงค่าอินพุตดั้งเดิม (สตริง, ตัวเลข, บูลีน, สัญลักษณ์) หรือการอ้างอิงอ็อบเจ็กต์ที่เปลี่ยนแปลง (วันที่อาร์เรย์ฟังก์ชันอ็อบเจ็กต์)

เชิงมุมละเว้นการเปลี่ยนแปลงภายในออบเจ็กต์ (คอมโพสิต) มันจะไม่เรียกท่อบริสุทธิ์ถ้าคุณเปลี่ยนเดือนอินพุตเพิ่มในอาร์เรย์อินพุตหรืออัปเดตคุณสมบัติวัตถุอินพุต

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

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


คำตอบนั้นถูกต้อง แต่พยายามมากขึ้นเมื่อโพสต์มันจะดี
Stefan

2

แทนที่จะทำบริสุทธิ์: เท็จ คุณสามารถคัดลอกและแทนที่ค่าในองค์ประกอบได้อย่างละเอียดโดย this.students = Object.assign ([], NEW_ARRAY); โดยที่ NEW_ARRAY คืออาร์เรย์ที่แก้ไข

ใช้งานได้กับ angular 6 และควรใช้กับรุ่นเชิงมุมอื่น ๆ ด้วย


0

วิธีแก้ปัญหา: นำเข้า Pipe ในตัวสร้างด้วยตนเองและเรียกวิธีการแปลงโดยใช้ไปป์นี้

constructor(
private searchFilter : TableFilterPipe) { }

onChange() {
   this.data = this.searchFilter.transform(this.sourceData, this.searchText)}

จริงๆแล้วคุณไม่จำเป็นต้องใช้ท่อ


0

เพิ่มไปยังไพพ์พารามิเตอร์พิเศษและเปลี่ยนทันทีหลังจากเปลี่ยนอาร์เรย์และแม้จะใช้ไปป์บริสุทธิ์รายการก็จะรีเฟรช

ให้ของรายการ | ท่อ: param


0

ในกรณีการใช้งานนี้ฉันใช้ไฟล์ Pipe ใน ts สำหรับการกรองข้อมูล จะดีกว่าสำหรับประสิทธิภาพมากกว่าการใช้ท่อบริสุทธิ์ ใช้ใน ts เช่นนี้:

import { YourPipeComponentName } from 'YourPipeComponentPath';

class YourService {

  constructor(private pipe: YourPipeComponentName) {}

  YourFunction(value) {
    this.pipe.transform(value, 'pipeFilter');
  }
}

0

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

            emp=[];
            empid:number;
            name:string;
            city:string;
            salary:number;
            gender:string;
            dob:string;
            experience:number;

            add(){
              const temp=[...this.emps];
              const e={empid:this.empid,name:this.name,gender:this.gender,city:this.city,salary:this.salary,dob:this.dob,experience:this.experience};
              temp.push(e); 
              this.emps =temp;
              //this.reset();
            } 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.