gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费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號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
黄网站欧美内射| 亚洲视频在线观看一区二区三区| 能在线观看的av网站| 亚洲 欧美 综合 另类 中字| 天天做天天干天天操| 伊人国产精品视频| 肉色超薄丝袜脚交| 中文字幕免费高| 日本网站在线看| 佐佐木明希av| 日韩 欧美 视频| 欧美国产激情视频| 亚洲五月天综合| 亚洲在线观看网站| 成年人视频大全| 男人操女人免费软件| 91蝌蚪视频在线观看| 视频区 图片区 小说区| www.黄色网址.com| 欧美精品自拍视频| 91香蕉视频导航| 国产大尺度在线观看| 日韩国产小视频| 欧美激情精品久久久久久小说| 日韩一级免费片| 国产欧美久久久久| 欧美视频免费播放| 日韩av片专区| 九色在线视频观看| 一级片黄色免费| 欧美 日本 亚洲| 亚洲男人天堂2021| 99蜜桃臀久久久欧美精品网站| 中文av一区二区三区| 欧洲精品在线播放| 国产永久免费网站| 成人黄色av片| 特级西西444| 国产三级三级看三级| 99在线观看视频免费| 色婷婷成人在线| 亚洲熟妇国产熟妇肥婆| jizzzz日本| 国产日产欧美视频| 人妻激情另类乱人伦人妻| 九色91popny| 国产乱子夫妻xx黑人xyx真爽| 黄色www在线观看| 国产美女18xxxx免费视频| 黑人糟蹋人妻hd中文字幕| 蜜桃视频一区二区在线观看| 亚洲高清免费在线观看| 国产免费成人在线| www.浪潮av.com| 国产成人一区二区三区别| 中文字幕av不卡在线| 91看片就是不一样| 欧美女人性生活视频| 蜜臀av.com| 国产又爽又黄ai换脸| 中文字幕成人免费视频| 2025韩国理伦片在线观看| 男人的天堂日韩| 一级特黄性色生活片| 久久久久人妻精品一区三寸| 日本www在线播放| 欧美牲交a欧美牲交aⅴ免费真| 国产 日韩 欧美在线| 免费成人午夜视频| 又粗又黑又大的吊av| 三级4级全黄60分钟| 国产wwwxx| 国产成年人视频网站| 亚洲综合123| 日本久久高清视频| 六月婷婷激情综合| 久久综合久久久久| 男女视频网站在线观看| 国产一区亚洲二区三区| 午夜宅男在线视频| 福利网在线观看| 黄色成人在线看| 久草综合在线观看| 2025韩国理伦片在线观看| 久久6免费视频| 久久在线中文字幕| 999精品视频在线| а 天堂 在线| 亚洲 高清 成人 动漫| 青青草av网站| 少妇一晚三次一区二区三区| 国产精品又粗又长| 手机在线成人免费视频| 在线观看av的网址| 99热手机在线| 欧美午夜性视频| 欧美v在线观看| 樱空桃在线播放| 久久久精品麻豆| 成人午夜视频免费观看| 亚洲五月天综合| 三上悠亚久久精品| 欧洲美女亚洲激情| 可以在线看的黄色网址| 国产三级中文字幕| 天天色综合天天色| 无码人妻精品一区二区三区在线 | 日韩欧美在线播放视频| 老司机久久精品| 波多野结衣家庭教师视频| 天天操狠狠操夜夜操| 日本三级免费网站| 香蕉视频在线网址| 99九九99九九九99九他书对| 成年人网站免费视频| 欧美 另类 交| 成年人三级黄色片| 天天爽夜夜爽一区二区三区| 国产午夜福利100集发布| 裸体裸乳免费看| 色撸撸在线观看| 色综合天天色综合| 国产成人无码av在线播放dvd| av在线播放天堂| 玖玖精品在线视频| 波多野结衣激情| 亚洲色图偷拍视频| 亚洲这里只有精品| 三级一区二区三区| www激情五月| 亚洲热在线视频| 看全色黄大色大片| 日韩成人手机在线| 免费一级特黄特色毛片久久看| 日韩成人三级视频| 欧美人成在线观看| 欧美深夜福利视频| 成人免费无码av| 天天爽人人爽夜夜爽| 天天看片天天操| 影音先锋成人资源网站| 日产精品久久久久久久蜜臀| 精品国产一区二区三区无码| av日韩在线看| 91av资源网| www日韩视频| 日本在线观看视频一区| 成人免费看片视频在线观看| 91午夜在线观看| 毛片一区二区三区四区| youjizzxxxx18| 欧美日韩一级在线| 欧美视频在线播放一区| 一区二区三区 欧美| 中文字幕一区久久| 日韩亚洲欧美视频| 亚洲爆乳无码专区| 性做爰过程免费播放| 精品99在线视频| 中文字幕线观看| 欧洲精品一区二区三区久久| aaa毛片在线观看| 操人视频免费看| 亚洲欧洲日产国码无码久久99| 日本成人在线免费视频| 日韩欧美色视频| 黄色一级一级片| 日韩video| 欧美少妇性生活视频| 麻豆映画在线观看| 日韩av播放器| 老子影院午夜伦不卡大全| a在线观看免费视频| 国内精品视频一区二区三区| 五月激情五月婷婷| 免费在线观看的av网站| 成人毛片100部免费看| 91激情视频在线| 国产婷婷一区二区三区| 成年人黄色在线观看| 国产精品视频分类| 日本一本中文字幕| 日韩视频在线观看视频| 一区二区成人网| 欧美 国产 日本| 九色在线视频观看| 国产a级片网站| 狠狠干视频网站| 91欧美一区二区三区| 男女污污的视频| 高清一区二区视频| 日本免费黄视频| 欧美极品欧美精品欧美图片| 欧美视频在线观看视频| 欧美这里只有精品| 日韩欧美视频免费在线观看| 大桥未久一区二区三区| 国产制服91一区二区三区制服| 国产又黄又猛的视频| 又色又爽又黄视频|