成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網(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號
国产思思99RE99在线观看| 国内女人喷潮完整视频| 国产乱码精品一区三上 | 男吃奶玩乳尖高潮视频午夜| 免费观看四虎精品国产地址| 欧美巨大XXXX做受高清| 日日摸夜夜摸狠狠摸婷婷| 无码国产精品一区二区免费久久| 亚洲AV熟妇高潮18P| 亚洲午夜无码久久久久| 中文字字幕在线中文乱码| 菠萝蜜国际通道一区麻豆| 国产黄A三级三级三级| 娇妻初尝粗大滋味借种韩国电影| 久久亚洲AV成人无码一区二区| 欧美XXXX做受性欧美88| 色老太BBWBBWBBW高潮| 性少妇中国内射XXXX狠干| 亚洲午夜国产精品无码| ASS亚洲熟妇毛茸茸PICS| 高潮好爽视频在线观看| 韩国免费A级毛片| 美女与野兽在线观看| 人人妻人人狠人人爽| 香草乱码一二三四区别| 一边做饭一边躁狂的原因分析| 99久久国产综合精品五月天喷水 | 日韩毛片无码永久免费看| 午夜福利麻豆国产精品| 一本一道波多野结衣AV一区| 宝贝小嫩嫩好紧好爽H在线视频| 国产女主播高潮在线播放| 久久综合亚洲色一区二区三区| 人妻无码系列一区二区三区| 亚洲AV成人无码网站大全| 伊人久久大香线蕉AV不卡| 成人免费A级毛片无码片在线播放| 国产亚洲精品拍拍拍拍拍 | 在线观看亚洲AV每日更新无码| 成年网站免费视频黄A站| 经典国产乱子伦精品视频| 女人扒下裤让男人桶到爽| 天天躁日日躁狠狠躁婷婷| 夜夜躁狠狠躁日日躁孕妇| 吃奶呻吟打开双腿做受在线视频 | 国产成A人亚洲精V品无码性色| 九九电影网午夜理论片| 日韩AV人人夜夜澡人人爽| 亚洲另类人妻小说| 成人乱码一区二区三区AV| 精品人人妻人人澡人人爽牛牛| 人妻丰满熟妞AV无码区| 亚洲国产精品线路久久| 爆乳2把你榨干哦OVA在线观看| 狠狠色噜噜狠狠狠狠色综合久AV| 青青草无码精品伊人久久蜜臀| 亚洲av无码成人精品区在线观看| A级毛片高清免费视频在线播放| 国产揄拍国产精品| 人妻少妇精品视频三区二区一区| 亚洲国产精品一区二区第一页| 餐桌下狂C亲女水欧阳凝| 久久久久精品无码一区二区三区| 上司侵犯部下的人妻| 在出租屋里被强高H| 国产欧美久久久久久精品一区二区| 欧美成人午夜免费全部完| 亚洲不乱码卡一卡二卡4卡5卡| 草莓丝瓜芭乐鸭脖奶茶搭配食物| 久久精品久久电影免费| 无码人妻久久1区2区3区| 7777久久亚洲中文字幕| 精品韩国亚洲AV无码不卡区| 特区爱奴在线观看| CHINESE猛攻打桩大学生| 久久99精品久久久久久久不卡| 特级毛片AAAAAA| JAPANESE军人强迫| 久久婷婷六月综合色液啪| 亚洲 日韩 欧美 成人 在线观 | 日日摸夜夜添夜夜添视频| 在线播放免费人成毛片乱码| 国语对白国产成人AⅤ片 | 欧美超大胆裸体XX视频| 亚洲熟妇AV一区二区三区浪潮| 国产精品国产AV片国产| 人人妻人人澡人人| 中文字幕亚洲综合久久蜜桃| 精品无码国产自产在线观看水浒传 | 中文字幕无码乱人伦| 精品国产国偷自产在线观看| 无码人妻丰满熟妇区BBBBXXXX| 菠萝菠萝蜜免费播放视频| 男女一边摸一边做爽爽| 野花视频在线观看| 含羞草自慰抽搐喷白浆AⅤ| 无码国产精成人午夜视频不卡| 爆乳无码AV一区二区三区小说| 免费视频成人片在线观看 | 精品无码国模私拍视频| 亚欧免费无码AⅤ在线观看| 国产AV无码专区亚洲AWWW| 人体内射精一区二区三区| …日韩人妻无码精品一专区| 久久久亚洲欧洲日产国码ΑV| 亚洲国产精品特色大片观看完整版| 国产精品久久久久7777按摩| 少妇人妻在线视频| 成人精品一区二区www| 人人爽人人澡人人人人妻| 99久久免费只有精品国产| 妺妺窝人体色聚窝窝www毛片| 一区二区三区高清AV专区| 久久国产精品无码网站| 亚洲精品成人久久AV| 好男人好视频资源在线播放| 性饥渴少妇做私密SPA| 国产精品自产拍在线观看| 铜铜铜铜铜铜铜铜铜好多深 | 他扒开内裤把舌头进去会有影响吗| 差差差软件大全APP推荐免费| 欧亚尺码专线欧洲B1B1| JAPANESE五十路熟女| 欧美性猛交XXXX乱大交3| A级黑粗大硬长爽 猛视频, | CAOPORN免费视频国产| 欧美日韩人妻精品| SEERX性欧美老妇| 欧美牲交视频免费观看| FREE性台湾娇小VIDEOS| 欧洲精品码一区二区三区| 把腿张开老子cao烂你n视频| 日本丰满岳乱妇在线观看| 穿着旗袍方便C英语老师| 少妇寂寞难耐被黑人中出| 丰满熟妇乱子又伦| 无码国产色欲XXXXX视频| 国产日韩AⅤ无码一区二区三区| 亚洲AV成人无码精品电影在线| 好爽又高潮了毛片免费下载| 亚洲精品无码专区久久久| 久久国产劲爆∧V内射| 有人有在线看片的吗www视频 | 国精一二三区别免费| 亚洲AV永久精品无码桃色| 九月在线 视频 在线观看| 影音先锋熟女少妇AV资源| 女人扒开的小泬高潮喷水小说| Xx性欧美肥妇精品久久久久久久久 | 麻花传媒0076在线观看| 8V蜜桃网最新电影| 人妻无码人妻有码中文字幕在线| 成人性生交大片免费看中文| 我和子发生了性关系视频| 国内久久婷婷五月综合欲色广啪| 亚洲婷婷月色婷婷五月| 免费看永久不收费下载软件| HEYZO无码综合国产精品| 色妞WWW精品免费视频| 国产日产欧产综合| 亚洲色丰满少妇高潮18P| 男男高H啊灌满了高潮视频| 成 人 黄 色 网 站 在线播| 婷婷色香五月综合激激情| 黑人异族巨大巨大巨粗| 在线观看片免费人成视频无码| 欧洲S码亚洲M码精品一区| 国产SUV精品一区二区883| 亚洲AV永久无码精品秋霞电影影 | 中文字幕亚洲欧美专区 | 成人免费无码不卡毛片视频| 无人区码一码二码三MBA| 久久国产精品波多野结衣AV| 99精品视频九九精品视频| 日韩精品区一区二区三VR| 国产又黄又爽又刺激的免费网址 | 国产成人精品视频ⅤA秋霞影院| 亚洲AV午夜成人片忘忧草在线| 老根嫩草1一40淑媛全文| 暴躁老姐的CSGO心得分享| 亚洲AⅤ无码一区二区波多野| 巨粗进入警花哭喊求饶| 成年女人18毛片毛片免费不卡| 亚洲AV蜜乳永久www| 免费人成在线观看网站免费观看| 第一次爱的人视频播放完整版| 亚洲AV无码一区东京热久久| 免费人成视频XVIDEOS| 国产AV成人精品播放| 亚洲日本VA午夜在线影院| 欧美性一区二区三区| 国产熟妇人妻ⅩXXXX麻豆网站| 一本一道波多野结衣一区| 色噜噜人妻丝袜aV先锋影音先| 精品国产成人A区在线观看| WC女厕撒尿七Ⅴ偷拍| 亚洲AV无码成人精品区明星换面| 妺妺窝人体色聚色窝www视频| 国产精品久久久久久影视不卡| 岳丰满多毛的大隂户|