第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

NgFor不使用Angular2中的Pipe更新數(shù)據(jù)

NgFor不使用Angular2中的Pipe更新數(shù)據(jù)

達(dá)令說 2019-07-26 11:38:36
NgFor不使用Angular2中的Pipe更新數(shù)據(jù)在這種情況下,我正在向視圖中顯示學(xué)生列表(數(shù)組)ngFor:<li *ngFor="#student of students">{{student.name}}</li>每當(dāng)我將其他學(xué)生添加到列表中時,它都會更新。然而,當(dāng)我給它一個pipe到filter由學(xué)生的名字,<li *ngFor="#student of students | sortByName:queryElem.value ">{{student.name}}</li>在我在過濾學(xué)生姓名字段中輸入內(nèi)容之前,它不會更新列表。這是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.tsimport {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;     }}
查看完整描述

3 回答

?
楊魅力

TA貢獻(xiàn)1811條經(jīng)驗 獲得超6個贊

為了完全理解問題和可能的解決方案,我們需要討論角度變化檢測 - 用于管道和組件。

管道變化檢測

無狀態(tài)/純管

默認(rèn)情況下,管道是無狀態(tài)/純粹的。無狀態(tài)/純管道只是將輸入數(shù)據(jù)轉(zhuǎn)換為輸出數(shù)據(jù)。他們不記得任何東西,所以他們沒有任何屬性 - 只是一種transform()方法。因此,Angular可以優(yōu)化無狀態(tài)/純管道的處理:如果它們的輸入沒有改變,則在變化檢測循環(huán)期間不需要執(zhí)行管道。對于管道,如{{power | exponentialStrength: factor}}powerfactor輸入。

對于這個問題,"#student of students | sortByName:queryElem.value",studentsqueryElem.value為輸入,并且管sortByName是無狀態(tài)/純的。 students是一個數(shù)組(引用)。

  • 添加學(xué)生時,數(shù)組引用不會更改 - students不會更改 - 因此不會執(zhí)行無狀態(tài)/純管道。

  • 當(dāng)在過濾器輸入中輸入某些內(nèi)容時,queryElem.value確實會更改,因此會執(zhí)行無狀態(tài)/純管道。

解決陣列問題的一種方法是每次添加學(xué)生時更改數(shù)組引用 - 即,每次添加學(xué)生時創(chuàng)建新數(shù)組。我們可以這樣做concat()

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

雖然這很有效,但我們的addNewStudent()方法不應(yīng)該僅僅因為我們使用管道而以某種方式實現(xiàn)。我們想用來push()添加到我們的數(shù)組中。

有狀態(tài)的管道

有狀態(tài)管道具有狀態(tài) - 它們通常具有屬性,而不僅僅是transform()方法。即使輸入沒有改變,也可能需要對它們進(jìn)行評估。當(dāng)我們指定管道是有狀態(tài)/非純的時 - pure: false- 每當(dāng)Angular的更改檢測系統(tǒng)檢查組件的更改并且該組件使用有狀態(tài)管道時,它將檢查管道的輸出,無論其輸入是否已更改。

這聽起來像我們想要的,即使它效率較低,因為我們希望管道執(zhí)行即使students引用沒有改變。如果我們只是使管道有狀態(tài),我們會收到一個錯誤:

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

根據(jù)@ drewmoore的回答,“此錯誤僅在開發(fā)模式下發(fā)生(默認(rèn)情況下從beta-0開始)。如果enableProdMode()在引導(dǎo)應(yīng)用程序時調(diào)用,則不會拋出錯誤?!?nbsp;國家文件ApplicationRef.tick()

在開發(fā)模式中,tick()還執(zhí)行第二個更改檢測周期,以確保不會檢測到進(jìn)一步的更改。如果在第二個周期中拾取了其他更改,則應(yīng)用中的綁定會產(chǎn)生無法在單個更改檢測過程中解決的副作用。在這種情況下,Angular會拋出一個錯誤,因為Angular應(yīng)用程序只能有一個更改檢測通道,在此期間必須完成所有更改檢測。

在我們的場景中,我認(rèn)為錯誤是虛假/誤導(dǎo)。我們有一個有狀態(tài)的管道,每次調(diào)用時輸出都會改變 - 它可能有副作用,這沒關(guān)系。NgFor在管道之后進(jìn)行評估,因此它應(yīng)該可以正常工作。

但是,我們無法真正開發(fā)此錯誤,因此一種解決方法是將數(shù)組屬性(即狀態(tài))添加到管道實現(xiàn)并始終返回該數(shù)組。請參閱@ pixelbits對此解決方案的回答。

但是,我們可以更高效,并且正如我們將看到的,我們將不需要管道實現(xiàn)中的數(shù)組屬性,并且我們不需要針對雙重更改檢測的變通方法。

組件變化檢測

默認(rèn)情況下,在每個瀏覽器事件中,角度變化檢測都會遍歷每個組件以查看它是否發(fā)生了變化 - 輸入和模板(以及其他東西?)都會被檢查。

如果我們知道組件僅依賴于其輸入屬性(和模板事件),并且輸入屬性是不可變的,那么我們可以使用更有效的onPush變更檢測策略。使用此策略,不會檢查每個瀏覽器事件,只有在輸入更改和模板事件觸發(fā)時才會檢查組件。而且,顯然,我們沒有Expression ... has changed after it was checked通過此設(shè)置獲得該錯誤。這是因為在onPush再次“標(biāo)記”(ChangeDetectorRef.markForCheck())之前不會再次檢查組件。因此,模板綁定和有狀態(tài)管道輸出僅執(zhí)行/評估一次。除非輸入改變,否則無狀態(tài)/純管道仍未執(zhí)行。所以我們?nèi)匀恍枰粋€有狀態(tài)的管道。

這是@EricMartinez建議的解決方案:帶有onPush變化檢測的有狀態(tài)管道。請參閱@ caffinatedmonkey對此解決方案的回答。

請注意,使用此解決方案時,該transform()方法不需要每次都返回相同的數(shù)組。我發(fā)現(xiàn)有點(diǎn)奇怪:沒有狀態(tài)的有狀態(tài)管道。再考慮一下......有狀態(tài)管道可能應(yīng)該總是返回相同的數(shù)組。否則,它只能與onPush開發(fā)模式下的組件一起使用。


畢竟,我認(rèn)為我喜歡@ Eric和@ pixelbits的答案的組合:有狀態(tài)管道返回相同的數(shù)組引用,onPush如果組件允許則進(jìn)行更改檢測。由于有狀態(tài)管道返回相同的數(shù)組引用,因此管道仍可用于未配置的組件onPush

Plunker

這可能會成為Angular 2的習(xí)慣用法:如果數(shù)組正在輸入管道,并且數(shù)組可能會更改(數(shù)組中的項目,而不是數(shù)組引用),我們需要使用有狀態(tài)管道。


查看完整回答
反對 回復(fù) 2019-07-26
  • 3 回答
  • 0 關(guān)注
  • 869 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號