日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态创建 @ViewChild 导致运行时错误的原因分析

發布時間:2023/12/19 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态创建 @ViewChild 导致运行时错误的原因分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文討論問題的代碼,位于 Github:https://github.com/wangzixi-diablo/ngDynamic

問題描述

我的 Component 代碼如下圖所示:

  • 使用依賴注入,引入 ViewContainerRef,從而可以使用其 createEmbeddedView 方法,在運行時動態創建實例。

  • 使用 @ViewChild,獲得該 Component HTML 源代碼里定義的 id 為 tpl 的模板實例,類型為 TemplateRef。

  • Component 的 HTML 源代碼:

  • <ng-template tpl><div>Hello, ng-template!</div> </ng-template>

    然而啟動應用,出現運行時錯誤:

    ERROR TypeError: Cannot read properties of undefined (reading ‘createEmbeddedView’)
    at ViewContainerRef.createEmbeddedView (core.js:10190:45)
    at NgTemplateComponent.push.8YnP.NgTemplateComponent.ngAfterViewInit (ng-template.component.ts:20:20)
    at callHook (core.js:3281:18)
    at callHooks (core.js:3251:17)
    at executeInitAndCheckHooks (core.js:3203:9)
    at refreshView (core.js:7451:21)
    at renderComponentOrTemplate (core.js:7494:9)
    at tickRootContext (core.js:8701:9)
    at detectChangesInRootView (core.js:8726:5)
    at RootViewRef.detectChanges (core.js:9991:9)

    問題分析

    上述調用上下文里,有一個棧幀是我們應用程序的代碼:

    ngAfterViewInit (ng-template.component.ts:20:20)

    在其方法內設置斷點, 發現運行時,this.tplRef 為空。

    在值為 undefined 的變量上調用 createEmbeddedView 導致的這個錯誤。

    問題轉化為:this.tplRef 的賦值邏輯是怎樣的?

    在 ngOnInit 時,這個屬性還是 undefined 狀態:

    我們把鼠標 hover 在 @ViewChild 上查看其說明:

    變更檢測器會在視圖的 DOM 中查找能匹配上該選擇器的第一個元素或指令。 如果視圖的 DOM 發生了變化,出現了匹配該選擇器的新的子節點,該屬性就會被更新。

    發現輸入參數是一個選擇器,本例我傳入的選擇器是 id 選擇器:tpl

    根據 Angular 官網文檔,這意味著我的 HTML 模板文件里,tpl 之前應該用 # 修飾:

    解決方案

    在 tpl 前添加 #:

    總結

    如果我們想進一步觀察 view query 是如何根據傳入的選擇器 tpl,去 dom tree 里查找的節點,可以添加如下代碼,即 @ViewChild 和 set 函數搭配使用的情況。

    @ViewChild('tpl')set thisNamedoesnotMatter(v:TemplateRef<any>){console.log('Jerry');this.tplRef = v;}

    通過調試,發現 view query 的執行過程不會顯示在 Chrome 開發者工具里,而僅僅顯示一個 dummy 的 XXX(Component 名稱)_Query 的調用上下文。

    set 函數里的輸入參數 v 代表的就是 id 為 tpl 的 Template 實例。

    總結

    以上是生活随笔為你收集整理的动态创建 @ViewChild 导致运行时错误的原因分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。