久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

淺析Angular變更檢測中的DOM更新機制

淺析Angular變更檢測中的DOM更新機制

前端(vue)入門到精通課程,老師在線輔導:聯系老師
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調試工具:點擊使用

變更檢測是Angular中很重要的一部分,也就是模型和視圖之間保持同步。在日常開發過程中,我們無需了解變更檢測,因為Angular都幫我們完成了這一部分工作,讓開發人員更加專注于業務實現,提高開發效率和開發體驗。但是如果想要深入使用框架,或者想要寫出高性能的代碼而不僅僅只是實現了功能,就必須要去了解變更檢測,它可以幫助我們更好的理解框架,調試錯誤,提高性能等。【相關教程推薦:《angular教程》】

Angular的DOM更新機制

我們先來看一個小例子。

淺析Angular變更檢測中的DOM更新機制

當我們點擊按鈕的時候,改變了name屬性,同時DOM自動被更新成新的name值。

那現在有一個問題,如果我改變name的值后,緊接著把DOM中的innerText輸出出來,它會是什么值呢?

import { Component, ViewChild, ElementRef } from '@angular/core';  @Component({   selector: 'my-app',   templateUrl: './app.component.html',   styleUrls: [ './app.component.css' ] }) export class AppComponent  {   name = 'Empty';    @ViewChild('textContainer') textContainer: ElementRef;    normalClick(): void {     this.name = 'Hello Angular';      console.log(this.textContainer.nativeElement.innerText);   } }
登錄后復制

你答對了嗎?

那這兩段代碼中到底發生了什么呢?

如果我們用原生JS來編寫這段代碼,那么點擊按鈕后的視圖肯定不會發生任何變化,而在Angular中卻讓視圖發生了變化,那它為什么會自動把視圖更新了呢?這離不開一個叫做zone.js的庫,簡單來說,它是對發生值改變的事件做了一些處理,這個會在后面的部分詳細講解,這里暫時知道這個就可以了。

如果我不想讓這個庫做這些處理,Angular還為我們提供了禁用zone.js的方法。

可以在main.ts中設置禁用zone.js。

import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';  import { AppModule } from './app/app.module'; import { environment } from './environments/environment';  if (environment.production) {   enableProdMode(); }  platformBrowserDynamic().bootstrapModule(AppModule, {   ngZone: 'noop' })   .catch(err => console.error(err));
登錄后復制

淺析Angular變更檢測中的DOM更新機制

當我們禁用zone.js,視圖并未發生更新。到源碼里找一下視圖更新的相關代碼。

 */ class ApplicationRef {     /** @internal */     constructor(_zone, _injector, _exceptionHandler, _initStatus) {         this._zone = _zone;         this._injector = _injector;         this._exceptionHandler = _exceptionHandler;         this._initStatus = _initStatus;         /** @internal */         this._bootstrapListeners = [];         this._views = [];         this._runningTick = false;         this._stable = true;         this._destroyed = false;         this._destroyListeners = [];         /**          * Get a list of component types registered to this application.          * This list is populated even before the component is created.          */         this.componentTypes = [];         /**          * Get a list of components registered to this application.          */         this.components = [];         this._onMicrotaskEmptySubscription = this._zone.onMicrotaskEmpty.subscribe({             next: () => {                 this._zone.run(() => {                     this.tick();                 });             }         });         ...     }  /**      * Invoke this method to explicitly process change detection and its side-effects.      *      * In development mode, `tick()` also performs a second change detection cycle to ensure that no      * further changes are detected. If additional changes are picked up during this second cycle,      * bindings in the app have side-effects that cannot be resolved in a single change detection      * pass.      * In this case, Angular throws an error, since an Angular application can only have one change      * detection pass during which all change detection must complete.      */     tick() {         NG_DEV_MODE && this.warnIfDestroyed();         if (this._runningTick) {             const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?                 'ApplicationRef.tick is called recursively' :                 '';             throw new RuntimeError(101 /* RuntimeErrorCode.RECURSIVE_APPLICATION_REF_TICK */, errorMessage);         }         try {             this._runningTick = true;             for (let view of this._views) {                 view.detectChanges();             }             if (typeof ngDevMode === 'undefined' || ngDevMode) {                 for (let view of this._views) {                     view.checkNoChanges();                 }             }         }         catch (e) {             // Attention: Don't rethrow as it could cancel subscriptions to Observables!             this._zone.runOutsideAngular(() => this._exceptionHandler.handleError(e));         }         finally {             this._runningTick = false;         }     }  }
登錄后復制

大致解讀一下,這個ApplicationRef是Angular整個應用的實例,在構造函數中,zone(zone庫)的onMicrotaskEmpty(從名字上看是一個清空微任務的一個subject)訂閱了一下。在訂閱里,調用了tick(),那tick里做了什么呢

思考: 上次說了最好訂閱不要放到constructor里去訂閱,這里怎么這么不規范呢?

當然不是,上次我們說的是Angular組件里哪些應該放constructor,哪些應該放ngOnInit里的情況。但這里,ApplicationRef人家是一個service呀,只能將初始化的代碼放constructor

在tick函數里,如果發現這個tick函數正在執行,則會拋出異常,因為這個是整個應用的實例,不能遞歸調用。然后,遍歷了所有個views,然后每個view都執行了detectChanges(),也就是執行了下變更檢測,什么是變更檢測,會在后面詳細講解。緊接著,如果是devMode,再次遍歷所有的views,每個view執行了checkNoChanges(),檢查一下有沒有變化,有變化則會拋錯(后面會詳細說這個問題,暫時跳過)。

那好了,現在也知道怎么能讓它更新了,就是要調用一下ApplicationReftick方法。

import { Component, ViewChild, ElementRef, ApplicationRef } from '@angular/core'; @Component({   selector: 'app-root',   templateUrl: './app.component.html',   styleUrls: ['./app.component.scss'] }) export class AppComponent  {   name = 'Empty';    @ViewChild('textContainer') textContainer: ElementRef = {} as any;    constructor(private app: ApplicationRef){}    normalClick(): void {     this.name = 'Hello Angular';      console.log(this.textContainer.nativeElement.innerText);      this.app.tick();   } }
登錄后復制

果然,可以正常的更新視圖了。

我們來簡單梳理一下,DOM的更新依賴于tick() 的觸發,zone.js幫助開發者無需手動觸發這個操作。好了,現在可以把zone.js啟用了。

那什么是變更檢測呢?繼續期待下一篇哦。

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
日韩一区精品视频| 久久久久久婷| av亚洲免费| 美日韩精品视频| 视频一区日韩| 国产精品久久久久久妇女| 国产精品久久久久久久久久齐齐 | 国产精品麻豆成人av电影艾秋| 91精品国产自产观看在线| 久热精品在线| 久久黄色影视| 三级在线看中文字幕完整版| 欧美91福利在线观看| 一本一道久久a久久| 欧美激情五月| 婷婷亚洲五月色综合| 欧美一区二区三区久久| 国产精品久久久久久久免费观看 | 视频在线在亚洲| 国产精品对白久久久久粗| 久久久久国产一区二区| 亚洲成av在线| 欧美一级二级视频| 亚洲天堂成人| 久久国产中文字幕| 欧美精品国产白浆久久久久| 老牛国内精品亚洲成av人片| 日韩精品91| 麻豆亚洲精品| 国产精品亚洲一区二区在线观看| 天堂8中文在线最新版在线| 夜夜精品视频| 久久精品人人| 日本不卡高清| 亚洲专区欧美专区| 日韩大片在线观看| 久久99伊人| 精品视频免费| 婷婷精品在线| 91久久午夜| 久久精品国产www456c0m| 国产黄大片在线观看| 日韩精品中文字幕第1页| 亚洲精品伊人| 欧美中文一区| 激情婷婷久久| 久久精品国产99国产| 日韩精品网站| 亚洲精品88| 久久男人av资源站| 黑人精品一区| 国产欧美88| 国产人成精品一区二区三| 亚洲精品三级| 亚洲精品高潮| 日本午夜精品视频在线观看| 日本国产亚洲| 国产精品久久久久久久久免费高清 | 国产视频亚洲| 蜜桃伊人久久| 日韩精品欧美成人高清一区二区| 中文字幕av一区二区三区四区| 美女av在线免费看| 黑人精品一区| 一区三区视频| 婷婷精品久久久久久久久久不卡| 日韩久久99| 国产激情一区| 日韩在线观看一区| 91九色精品| 日本不卡视频在线| 欧美激情视频一区二区三区在线播放| 欧美激情日韩| 精品欧美激情在线观看| 中文字幕乱码亚洲无线精品一区| 热久久久久久| 国产精品99视频| 国产精品88久久久久久| 蜜臀av国产精品久久久久 | 欧美在线亚洲综合一区| 日韩久久99| 四虎国产精品免费观看| 国产精品毛片| 美女视频黄久久| 免费久久久久久久久| 91福利精品在线观看| 国产亚洲在线| 亚洲欧美一级| 精品国产乱码久久久久久1区2匹| 欧美精品一区二区三区精品| **爰片久久毛片| 日韩欧美在线中字| 欧美亚洲自偷自偷| 亚洲大片在线| 久久精品二区亚洲w码 | 精品淫伦v久久水蜜桃| 香蕉久久久久久久av网站| 美女性感视频久久| 亚洲日本免费电影| 99国产精品久久久久久久成人热 | 国产高潮在线| 国产免费av一区二区三区| av一区二区高清| 中文字幕在线视频久| 国产视频一区二| 亚洲精品欧美| 午夜在线精品偷拍| 亚洲国产专区| 日本综合字幕| 久久久男人天堂| 亚洲www啪成人一区二区| 国产一区二区三区视频在线| 免费污视频在线一区| 日本va欧美va瓶| 亚洲激情国产| 97精品国产| 国产欧美成人| 亚洲精品欧美| 欧美日韩国产综合网| 精品资源在线| 美女精品视频在线| 精品国产乱码久久久久久樱花| 国产精品亚洲四区在线观看| 欧美亚洲网站| 国产精品亲子伦av一区二区三区| 日韩和欧美的一区| 欧美日韩在线精品一区二区三区激情综合| 爽好久久久欧美精品| 亚洲另类av| 青青草国产成人99久久| 丝袜亚洲另类欧美| 免费在线成人网| 午夜精品亚洲| 免播放器亚洲一区| 国产精品亚洲欧美一级在线| 久久久久伊人| 久久久久久久久丰满| 亚洲欧洲一区| 日本视频一区二区| 国产66精品| 国产精品日韩| 国产精品一区二区美女视频免费看| 欧美国产不卡| 日韩精品看片| 综合亚洲自拍| 日韩精品五月天| 色乱码一区二区三区网站| 欧美~级网站不卡| 国产亚洲欧美日韩精品一区二区三区| 国产精品sss在线观看av| 四虎4545www国产精品 | 国产图片一区| 激情久久久久久| 视频一区中文字幕| 国产aⅴ精品一区二区四区| 日韩亚洲国产欧美| 老鸭窝一区二区久久精品| 夜久久久久久| 精品视频久久| 亚洲日本三级| 不卡av一区二区| 久久99精品久久久久久园产越南| 精品91久久久久| 欧美极品一区二区三区| 亚洲免费毛片| 国产 日韩 欧美 综合 一区| 视频福利一区| 色8久久久久| 国产精品传媒麻豆hd| 国精品一区二区| 精品深夜福利视频| 蜜芽一区二区三区| www.com.cn成人| 国产精品3区| 日本欧美一区二区| 中文亚洲免费| 国产伊人精品| 日韩国产一区二区| 精品国产一区二区三区2021| 日韩国产在线观看| 石原莉奈一区二区三区在线观看| 日韩在线高清| 欧美三级精品| 麻豆91在线播放| 国产精品v亚洲精品v日韩精品| 日本aⅴ精品一区二区三区 | 国产成人免费| 精品国产亚洲日本| 国产精品久久| 成人午夜毛片| 亚洲精品一级二级| 在线人成日本视频| 成人精品亚洲| 伊人久久大香线蕉av超碰演员| 在线天堂中文资源最新版| 日韩1区2区| 欧美特黄a级高清免费大片a级| 午夜在线精品偷拍| 日韩高清一级| 国产精品毛片aⅴ一区二区三区|