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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

ngzorro html源码,Angular 中 ngTemplateOutlet 的用法以及ng-zorro源码分析!

發(fā)布時間:2023/12/18 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ngzorro html源码,Angular 中 ngTemplateOutlet 的用法以及ng-zorro源码分析! 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、引言

今天看到文章:https://segmentfault.com/a/1190000015944548 。于是專門研究一下ngTemplateOutlet用法!!!!

官方定義 :

NgTemplateOutlet:?它是結(jié)構(gòu)指令,根據(jù)一個提前備好的插入一個內(nèi)嵌視圖。 你可以通過設(shè)置來給附加一個上下文對象。是一個對象,該對象的 key 可在模板中使用let語句進行綁定。

示例:?

*我測試:? 都可承載這個指令,?但不支持

這樣的標簽,提示:

使用目的

需要要自定義標題或頁腳的內(nèi)容。

比如編寫彈窗組件,不建議在組件模板中寫死標題和頁腳的內(nèi)容,當在頁面上使用該組件時,?頁面可以動態(tài)向指定組件內(nèi)占位傳入“一些內(nèi)容”,組件會把它們插入到它想要的地方!

比如ng-zorro中,也大量這樣用法,https://ng.ant.design/components/card/zh#components-card-demo-simple

二、組件自定義輸入內(nèi)容

比如在一個頁面上,引用nz-card時,把主頁面上內(nèi)容插入到nz-card中去,文檔上示例代碼:

如果要編寫這樣的組件,需要考慮幾個問題,

1、如何引用主頁面上的一個模板元素? ?(?使用本地變量 #,我記得以前官方文檔叫“局部模版變量"或“模板引用變量”)

2、引用的變量如何傳遞給子組件中? ? ? (子組件定義@Input? ,使用類型為TemplateRef的變量接收)

3、子組件如何使用這個引用變量? ? ? ? ? (?在模版中,用ngTemplateOutlet? 綁定這個變量即可)

4、引用的模板元素從主頁面上來,? 如何把子組件的數(shù)據(jù)(即子組件中上下文)傳遞給這個引用元素上來?(向ngTemplateOutlet?傳入?context: myContext”)

上下文傳遞很重要。組件為了使用上的靈活,一部分內(nèi)容定義在組件之外的(即主頁面上),當它插入到子組件中的時候,必然要顯示子組件內(nèi)的一些數(shù)據(jù),它才有意義。

ngTemplateOutlet?不僅用于綁定元素,還負責把子組件中的一個數(shù)據(jù)上下文傳遞進去.

5、模板元素如何使用上下文? (使用 模板輸入變量let?的形式,接收上下文屬性值,再用? {{? }}語法插入值)

定義上下文數(shù)據(jù)時,? myContext = { $implicit: 'World', valueInContent: "子組件內(nèi)的value" };

$implicit:是默認導出值。當let-item? 后沒=?號時,item引用它。

當?let-

valueInContent

=valueInContent?時,在模板元素內(nèi)部可以插值{{valueInContent}}

參考官方文檔:

完整而精巧的小例子,包含上面5個要點,要認真融會貫通呀:

源碼如下:

/// 主頁面

@Component({

selector: 'app-root',

template: `

Angular's ngTemplateOutlet 完整示意-----我是主頁

Hello {{name}}! 組件內(nèi)的上下文綁定: {{valueInContent}} ....主頁面的變量綁定: {{valueInApp}}

`,

})

export class AppComponent {

public valueInApp = "valueInApp :)";

}

/// 一個子組件

@Component({

selector: 'app-content',

template: `

我是子組件,下面的內(nèi)容是動態(tài)加載 :)

*ngTemplateOutlet="dynamicRef context: myContext">

`,

})

export class AppContent {

display = false;

@Input() dynamicRef: TemplateRef;

myContext = { $implicit: 'World', valueInContent: "子組件內(nèi)的value" };

}

三、ng-zorro?的組件的實現(xiàn)

支持TemplateRef參數(shù)的組件的實現(xiàn)

ng-zorro中,大量的組件的參數(shù)支持傳入模板引用,它的使用無處不在,要研究框架是如何實現(xiàn)的傳入模板引用的參數(shù)。

以nz-card為例,它的API說明:

凡是支持插入外部的模板引用的參數(shù),? ?它們的類型就是: string|TemplateRef ? ?或者? TemplateRef

翻看ng-zorro的nz-card 源碼,摘引如下,現(xiàn)在看它是不是超級簡單:

// 組件TS

@Input() nzExtra: string | TemplateRef;

// 組件HTML

{{ nzExtra }}

// 組件TS

@Input() nzActions: Array> = [];

// 組件HTML

對于TemplateRef的參數(shù),?直接用[ngTemplateOutlet]?來綁定即可。框架使用ngTemplateOutlet的方式和我們上一節(jié)看到的一樣。

我測試[ngTemplateOutlet]?不可綁定上下文,但*ngTemplateOutlet就可以,所以我們盡量使用*的格式吧!

對于string|TemplateRef的參數(shù),用*nzStringTemplateOutlet來綁定,這是什么鬼東西呢?

*nzStringTemplateOutlet探險

*nzStringTemplateOutlet?是ng-zorro官方擴展的指令,很實用且復(fù)雜的指令,它即接受string|TemplateRef的兩種參數(shù)值,插入到子組件的模板中去。

現(xiàn)在要小心翼翼的進入源碼探險之旅了!

2個知識必備:

1、構(gòu)造函數(shù)注入變量,

viewContainer代表指令的宿主元素,此處它承擔渲染容器的作用,

defalultTemplate注入的是宿主元素的內(nèi)容元素,就是上面的{{nzExtra}}部分。

// 注入viewContainer 宿主元素, 注入 defaultTemplate的 TemplateRef

constructor(private viewContainer: ViewContainerRef, private defaultTemplate: TemplateRef) {}

為什么能這樣注入變量,這得參見官方文檔:

viewContainer注入:

defalultTemplate注入:

2、動態(tài)創(chuàng)建EmbeddedView,? 這是動態(tài)組件時,經(jīng)常要使用的函數(shù)!

this.viewContainer.createEmbeddedView( 模版引用,上下文數(shù)據(jù) ); //返回一個EmbeddedView

分析源碼邏輯

使用nzStringTemplateOutlet的情景如下,nzExtra的值:string? |? TemplateRef?兩種可能:

{{ nzExtra }}

1、首先獲得各自的 ?TemplateRef?對象。 (見上圖紅綠線)

參數(shù)為:字符串string時,? ? ? ? ? ? 通過注入,? ? ? ? {{nzExtra}}??==>?defalultTemplate.

參數(shù)為:模板TemplateRef時,? ? ?通過指令賦值,?把?變量nzExtra==>inputTemplate.

2、創(chuàng)建EmeddedView。

使用viewContainer.createEmbeddedView方法,? 把TemplateRef和上下文來生成View.

3、監(jiān)聽指令ngOnChanges。

4、判斷是否重新創(chuàng)建視圖。因為用戶動態(tài)修改引用或上下文時,整個視圖要重建!

是否重建View,就是判斷nzStringTemplateOutletContext, nzStringTemplateOutlet?是否變化

a)? 如果nzStringTemplateOutlet第一次賦值,或nzStringTemplateOutlet變化前后不都是string,?要重建視圖

b)? 如果nzStringTemplateOutletContext?的屬性shape有變化時,也要重建視圖。

(注:新上下文的屬性比舊上下文屬性個數(shù)多時才變化,?若只是屬性值變化,是不用更新視圖)

5、若需要重建視圖,則重建視圖。

6、無需重建視圖,則進一步判斷是否是TemplateRef參數(shù)情況,如果上下文數(shù)據(jù)變化了,動態(tài)更新EmeddedView的值!

通過以上源碼,nzStringTemplateOutlet指令就可以監(jiān)聽綁定模板變化,以及上下文數(shù)據(jù)變化,更新視圖。?正由于這個指令強大,方便,我們在使用ng-zorro的組件時,才倍感方便順手。

綁定上下文件的語法

最后,在ng-zorro源碼中,搜索 nzStringTemplateOutlet綁定上下文時的語法,引自nz-form-control源碼:

// ng-zorro的官方寫法

{{ nzSuccessTip }}

突然很意外,為什么不是下面這樣使用??為什么寫context就能自動賦值到nzStringTemplateOutletContext上去??

可能這是由于Angular編譯時,特殊的處理吧!

// 這個寫法編譯報錯,container 不存在nzStringTemplateOutletContext屬性

[nzStringTemplateOutletContext]="{$implicit:validateControl}“ >

{{ nzSuccessTip }}

四、它的同類指令:NgComponentOutlet

偶然看到Common?模塊中,還有NgComponentOutlet指令,根據(jù)名稱也能猜出它的作用,直接把一個組件綁定過來,此時只要傳遞一個組件的類名即可!

我想起去年編寫實時數(shù)據(jù)看板的功能時,每一個看板的子組件是根據(jù)配置,動態(tài)生成一個類的工廠函數(shù),再創(chuàng)建類view,再插入到相應(yīng)的containerview中去。

當時以為很完美的方法,其實是繞了很多彎路,直接用NgComponentOutlet一句話不就夠了嗎,當時真的蠢,不過看了許多文章,也沒有講到這個指令的地方。Angular的知識點太多太碎了呀!

總結(jié)

以上是生活随笔為你收集整理的ngzorro html源码,Angular 中 ngTemplateOutlet 的用法以及ng-zorro源码分析!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。