gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

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

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

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

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

Angular的DOM更新機制

我們先來看一個小例子。

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

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

那現(xiàn)在有一個問題,如果我改變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);   } }
登錄后復制

你答對了嗎?

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

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

如果我不想讓這個庫做這些處理,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,視圖并未發(fā)生更新。到源碼里找一下視圖更新的相關代碼。

 */ 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整個應用的實例,在構造函數(shù)中,zone(zone庫)的onMicrotaskEmpty(從名字上看是一個清空微任務的一個subject)訂閱了一下。在訂閱里,調(diào)用了tick(),那tick里做了什么呢

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

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

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

那好了,現(xiàn)在也知道怎么能讓它更新了,就是要調(diào)用一下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() 的觸發(fā),zone.js幫助開發(fā)者無需手動觸發(fā)這個操作。好了,現(xiàn)在可以把zone.js啟用了。

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

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
日韩精品一区二区在线视频| 中文字幕66页| 国产一区二区三区播放| 色乱码一区二区三区在线| 日本三级免费观看| 国产裸体免费无遮挡| 久久久精品三级| 99久久激情视频| 成年人观看网站| 国产性生交xxxxx免费| 免费在线观看的毛片| 国产无套粉嫩白浆内谢的出处| av黄色在线网站| 久久综合久久色| 色婷婷狠狠18| 亚洲制服中文字幕| 国产麻豆电影在线观看| 99久久久精品视频| 精品国偷自产一区二区三区| 国产精品一区二区免费在线观看| 各处沟厕大尺度偷拍女厕嘘嘘| 欧美网站免费观看| 亚洲第一狼人区| 97超碰免费观看| 免费毛片网站在线观看| 国产又黄又猛视频| 久久久成人精品一区二区三区| 青青青青在线视频| 免费看黄色一级大片| 黄色网址在线免费看| 欧美精品99久久| 一本色道久久亚洲综合精品蜜桃| 亚洲自拍第三页| 欧美二区在线视频| 香蕉视频色在线观看| 黄色片网址在线观看| 日韩不卡一二三| 久久综合亚洲精品| 国产又粗又长又大的视频| avove在线观看| 男人的天堂日韩| 国产日韩欧美大片| 簧片在线免费看| 日韩在线综合网| 五月天激情图片| 亚洲综合av在线播放| 怡红院av亚洲一区二区三区h| 天堂视频免费看| 色综合av综合无码综合网站| 久久国产精品免费观看| 色戒在线免费观看| 成人在线观看a| 日韩精品在线中文字幕| 三级黄色片免费看| 国产三级精品三级在线| chinese少妇国语对白| 免费看黄在线看| 97精品国产97久久久久久粉红| 国产主播中文字幕| 久久久久久久久久久久久久国产| 国产精品视频二| 妞干网这里只有精品| 最近中文字幕免费mv| 中文字幕日韩久久| 99中文字幕在线| 午夜视频在线观| 午夜精品免费看| 加勒比av中文字幕| 不卡中文字幕在线观看| 九九久久久久久| 日本高清xxxx| 99er在线视频| 无码av天堂一区二区三区| 91.com在线| 国产肥臀一区二区福利视频| 亚洲精品蜜桃久久久久久| 日韩精品免费一区| 日韩精品xxxx| 激情内射人妻1区2区3区| 欧美少妇性生活视频| 亚洲一区在线不卡| 日本中文字幕在线不卡| 久久观看最新视频| 国产av麻豆mag剧集| 欧美视频在线观看网站| 激情婷婷综合网| 99国产精品久久久久久| 免费日韩在线观看| 超碰网在线观看| 91极品视频在线观看| 成人性做爰片免费视频| www.射射射| 中文字幕av专区| 国产91沈先生在线播放| 亚洲精品无码久久久久久| 日日干夜夜操s8| 久久久久久免费看| 污污网站免费看| 国产玉足脚交久久欧美| 手机看片一级片| 99在线精品免费视频| 一区二区成人网| 日本福利视频一区| 污污的视频免费观看| 国产精品久久国产| 午夜精品中文字幕| 色综合久久久久无码专区| 日本不卡一区在线| 黄色a级片免费| 国产美女作爱全过程免费视频| 国产一区亚洲二区三区| 大胆欧美熟妇xx| 五月天av在线播放| 欧美日韩激情视频在线观看| 特色特色大片在线| 欧美第一页浮力影院| 丰满爆乳一区二区三区| 大西瓜av在线| 永久免费黄色片| 九九热精品在线播放| 欧美综合在线观看视频| 精品无码一区二区三区爱欲| 亚洲综合激情五月| 韩国视频一区二区三区| 97xxxxx| 一二三四视频社区在线| 992tv快乐视频| 免费观看中文字幕| 三日本三级少妇三级99| 免费精品99久久国产综合精品应用| 91传媒久久久| 欧美 国产 日本| 精品中文字幕av| 日本免费黄视频| 久久精品网站视频| 国产激情在线观看视频| 天天爽天天爽夜夜爽| 欧美日韩亚洲一二三| 一区二区三区韩国| www.色就是色.com| 日本一二三区在线| 日本一道在线观看| 免费拍拍拍网站| a级黄色一级片| 成人在线观看黄| 久久婷婷综合色| 欧美 另类 交| 成人小视频在线观看免费| 日韩在线观看a| 黑鬼大战白妞高潮喷白浆| 免费看又黄又无码的网站| 蜜臀久久99精品久久久酒店新书| 久久久久久久少妇| 日韩va在线观看| 青草网在线观看| 成人在线观看a| 中文字幕一区久久| 2018国产在线| 欧美女同在线观看| a级片一区二区| 无码精品国产一区二区三区免费| 国产一二三区av| 免费高清一区二区三区| 久久久免费视频网站| 欧美一级特黄aaa| 毛片在线视频播放| 人人爽人人爽av| 久草资源站在线观看| 中文字幕亚洲影院| 能在线观看的av| 天天做天天爱天天高潮| 男女曰b免费视频| 欧美交换配乱吟粗大25p| 久久久国产欧美| 女人色极品影院| 亚洲精品www.| 精品少妇一区二区三区在线| 亚洲成人手机在线观看| 337p粉嫩大胆噜噜噜鲁| 91麻豆天美传媒在线| 中文字幕天天干| 91猫先生在线| 分分操这里只有精品| 亚洲黄色片免费看| 亚洲一级片网站| 日韩免费毛片视频| 久久国产午夜精品理论片最新版本| 欧美美女性视频| 亚洲一区二区蜜桃| 成年人视频观看| 91国在线高清视频| 免费在线观看污污视频| 成人日韩在线视频| 15—17女人毛片| 自拍偷拍一区二区三区四区| av免费观看网| 天天摸天天碰天天添| 亚洲熟女乱色一区二区三区| 亚洲一区二区三区av无码| 精品少妇人妻av一区二区|