如何解決angula中使用iframe點(diǎn)擊后不執(zhí)行變更檢測(cè)的問(wèn)題

這篇文章主要講解了如何解決angula中使用iframe點(diǎn)擊后不執(zhí)行變更檢測(cè)的問(wèn)題,內(nèi)容清晰明了,對(duì)此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會(huì)有幫助。

我們提供的服務(wù)有:網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、曲水ssl等。為成百上千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢(xún)和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的曲水網(wǎng)站制作公司

這個(gè)問(wèn)題是上周的,當(dāng)時(shí)覺(jué)得這個(gè)問(wèn)題的解決辦法太簡(jiǎn)單了,不用寫(xiě)博客記錄,但是潘老師今天今天又遇到了需要使用這個(gè)的地方,感覺(jué)問(wèn)題雖然不難,但是,寫(xiě)篇博客,方便自己查詢(xún),也給了其他人搜索到解決辦法的機(jī)會(huì)。

問(wèn)題描述

項(xiàng)目中使用到了ifame,理想狀態(tài)是:當(dāng)點(diǎn)擊ifame中的按鈕時(shí),將會(huì)調(diào)用通過(guò)angular寫(xiě)的一個(gè)函數(shù),函數(shù)將會(huì)修改一個(gè)ngif的判斷條件,顯示一個(gè)彈窗,

但現(xiàn)實(shí)是:當(dāng)點(diǎn)擊ifame中的按鈕時(shí),將會(huì)調(diào)用通過(guò)angular寫(xiě)的一個(gè)函數(shù),函數(shù)將會(huì)修改一個(gè)ngif的判斷條件,然后就沒(méi)有然后了.

如何解決angula中使用iframe點(diǎn)擊后不執(zhí)行變更檢測(cè)的問(wèn)題 

開(kāi)始的時(shí)候自己直接懵了, 方法確實(shí)執(zhí)行了, 但界面沒(méi)修改, 問(wèn)了問(wèn)潘老師, 潘老師說(shuō)看看生命周期函數(shù)是否執(zhí)行了, 果然, 所有的生命周期函數(shù)都沒(méi)有調(diào)用。

解決辦法

既然生命周期函數(shù)沒(méi)調(diào)用,我們讓他調(diào)用不就行了,值已經(jīng)變化了,但是界面不變化,說(shuō)明,angular 不知道值變化了,所以我們可以讓angular 主動(dòng)進(jìn)行變更檢測(cè),讓它知道已經(jīng)發(fā)生了變化。

對(duì)此我們可以使用 ChangeDetectorRef

變化監(jiān)測(cè)類(lèi) - ChangeDetectorRef

Angular 在整個(gè)運(yùn)行期間都會(huì)為每一個(gè)組件創(chuàng)建 ChangeDetectorRef 的實(shí)例,該實(shí)例提供了相關(guān)方法來(lái)手動(dòng)管理變化監(jiān)測(cè)。有了這個(gè)類(lèi),我們自己就可以自定義組件的變化監(jiān)測(cè)策略了,如停止/啟用變化監(jiān)測(cè)或者按指定路徑變化監(jiān)測(cè)等等。

它有以下方法:

  • markForCheck():把根組件到該組件之間的這條路徑標(biāo)記起來(lái),通知Angular在下次觸發(fā)變化監(jiān)測(cè)時(shí)必須檢查這條路徑上的組件。
  • detach():從變化監(jiān)測(cè)樹(shù)中分離變化監(jiān)測(cè)器,該組件的變化監(jiān)測(cè)器將不再執(zhí)行變化監(jiān)測(cè),除非再次手動(dòng)執(zhí)行reattach()方法。
  • reattach():把分離的變化監(jiān)測(cè)器重新安裝上,使得該組件及其子組件都能執(zhí)行變化監(jiān)測(cè)。
  • detectChanges():手動(dòng)觸發(fā)執(zhí)行該組件到各個(gè)子組件的一次變化監(jiān)測(cè)。

所以,我們可以使用 detectChanges() 來(lái)達(dá)到目標(biāo)

使用方法

// 在組件中注入
 constructor(private changeDetectorRef: ChangeDetectorRef) {
 }
 
 // 直接使用
 test() {
 this.changeDetectorRef.detectChanges()
 }

angular何時(shí)進(jìn)行變化檢測(cè)

總結(jié)起來(lái), 主要有如下幾種情況:

  • 用戶(hù)輸入操作,比如點(diǎn)擊,提交等
  • 請(qǐng)求服務(wù)端數(shù)據(jù)(XHR)
  • 定時(shí)事件,比如 setTimeout , setInterval

Angular并不是捕捉對(duì)象的變動(dòng),它采用的是在適當(dāng)?shù)臅r(shí)機(jī)去檢驗(yàn)對(duì)象的值是否被改動(dòng),這個(gè)時(shí)機(jī)就是這些異步事件的發(fā)生。

這個(gè)時(shí)機(jī)是由 Zone.js 去掌控的,它獲取到了整個(gè)應(yīng)用的執(zhí)行上下文,能夠?qū)ο嚓P(guān)的異步事件發(fā)生、完成或者異常等進(jìn)行捕獲,然后驅(qū)動(dòng) Angular 的變化監(jiān)測(cè)機(jī)制執(zhí)行。

Zone.js的作用

實(shí)際上 Zone,js 有一個(gè)叫猴子補(bǔ)丁的東西。在 Zone.js 運(yùn)行時(shí),就會(huì)為這些異步事件做一層代理包裹,也就是說(shuō)Zone.js運(yùn)行后,調(diào)用 setTimeout、addEventListener 等瀏覽器異步事件時(shí),不再是調(diào)用原生的方法,而是被猴子補(bǔ)丁包裝過(guò)后的代理方法。代理里setup了鉤子函數(shù), 通過(guò)這些鉤子函數(shù), 可以方便的進(jìn)入異步任務(wù)執(zhí)行的上下文

//以下是Zone.js啟動(dòng)時(shí)執(zhí)行邏輯的抽象代碼片段
function zoneAwareAddEventListener() {...}
function zoneAwareRemoveEventListener() {...}
function zoneAwarePromise() {...}
function patchTimeout() {...}
window.prototype.addEventListener=zoneAwareAddEventListener;
window.prototype.removeEventListener=zoneAwareRemoveEventListener;
window.prototype.promise = zoneAwarePromise;
window.prototype.setTimeout = patchTimeout;

關(guān)于 Zone.js 的詳細(xì)內(nèi)容可以看 這篇文章 。

angular變化檢測(cè)策略

angular 提供了兩種變更檢測(cè)策略,除了上述得Default外還有一種 OnPush 的檢測(cè)機(jī)制

OnPush 與 Default 之間的差別: 當(dāng)檢測(cè)到與子組件輸入綁定的值沒(méi)有發(fā)生改變時(shí),變化檢測(cè)就不會(huì)深入到子組件中去 。

一個(gè)OnPush的例子

app.comonent.ts

@Component({
 selector: 'app-root',
 template: `
 <h2>{{title}}</h2>
 <h3>user.name: {{user.name}}</h3>
 <button type="button" (click)="changeUserName()"> 改變屬性
 </button>
 <button type="button" (click)="changeUserObject()">
  改變對(duì)象
 </button>
 <app-test [user]="user"></app-test>
 `,
})
export class AppComponent {
 title = 'OnPush Demo';
 user: User = new User({name: 'yunzhi'});

 changeUserName() {
 this.user.name = 'new name';
 }

 changeUserObject() {
 this.user = new User({name: 'new user'});
 }
}

test.component.ts

@Component({
 selector: 'app-test',
 template: `
 <div>
  <h4>test 組件</h4>
  <p>
  <label>User:</label>
  <span>{{user.name}}</span>
  </p>
 </div>`,
 // 使用OnPush模式只需要加上下面這段代碼
 changeDetection: ChangeDetectionStrategy.OnPush
})
export class TestComponent implements OnInit {
 @Input() user: User;

 constructor() {
 }

 ngOnInit() {
 }

}

這時(shí)當(dāng)我們點(diǎn)擊改變屬性按鈕時(shí)test組件顯示的并不會(huì)變化,只有改變user得引用test組件顯示的才會(huì)變化,如下圖所示

如何解決angula中使用iframe點(diǎn)擊后不執(zhí)行變更檢測(cè)的問(wèn)題

看完上述內(nèi)容,是不是對(duì)如何解決angula中使用iframe點(diǎn)擊后不執(zhí)行變更檢測(cè)的問(wèn)題有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

名稱(chēng)欄目:如何解決angula中使用iframe點(diǎn)擊后不執(zhí)行變更檢測(cè)的問(wèn)題
網(wǎng)頁(yè)網(wǎng)址:http://bm7419.com/article20/pcggjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、虛擬主機(jī)、做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、域名注冊(cè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)