目錄
那麼模板輸入變數到底是什麼
上下文对象是如何设置的
自定义一个简单的类*ngFor指令——appRepeat
原神1.5版本卡池角色
自定义ngFor(appRepeat)
真正的ngFor
總結
結語
首頁 web前端 js教程 詳解Angular中的模板輸入變數(let-變數)

詳解Angular中的模板輸入變數(let-變數)

May 06, 2021 am 10:13 AM
angular

本篇文章帶大家來了解Angular中的範本輸入變數(let-變數)。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

詳解Angular中的模板輸入變數(let-變數)

我這個人,寫文章或說心得,不喜歡直接抄官網上面的東西,實在沒啥意思。我還是喜歡用我的大白話來寫文章。今天這個關於模板輸入變數的這個我今天啃官網啃了許久,總算是初步的了解了是啥東西。

那麼模板輸入變數到底是什麼

我想研究這玩意的起因在於之前我使用ng-zorro的時候,用到了它的分頁元件Pagination官網連結)。這其中有一個自訂上一頁下一頁範本的功能。程式碼的話如下:

@Component({
  selector: 'nz-demo-pagination-item-render',
  template: `
    <nz-pagination [nzPageIndex]="1" [nzTotal]="500" [nzItemRender]="renderItemTemplate"></nz-pagination>
    <ng-template #renderItemTemplate let-type let-page="page">
      <ng-container [ngSwitch]="type">
        <a *ngSwitchCase="&#39;page&#39;">{{ page }}</a>
        <a *ngSwitchCase="&#39;prev&#39;">Previous</a>
        <a *ngSwitchCase="&#39;next&#39;">Next</a>
        <a *ngSwitchCase="&#39;prev_5&#39;"><<</a>
        <a *ngSwitchCase="&#39;next_5&#39;">>></a>
      </ng-container>
    </ng-template>
  `
})
export class NzDemoPaginationItemRenderComponent {}
登入後複製

看完這個之後我就很是疑惑,這個let是啥,為啥let-跟上一個變數之後就有值了呢?然後我就開始在官網找這個let是什麼。最終,我在主要概念-指令-結構性指令微語法一節找到了關於let的說明。官網描述:微語法。 【相關推薦:《angular教學》】

在下面還有一段簡短的說明:

範本輸入變數(Template input variable)

模板輸入變數是這樣一種變量,你可以在單一實例的模板中引用它的值。這個範例中有好幾個模板輸入變數:heroiodd。它們都是用 let 作為前導關鍵字。

......

你使用let 關鍵字(如let hero)在範本中宣告一個範本輸入變數。這個變數的範圍被限制在所重複模板的單一實例上。事實上,你可以在其它結構型指令中使用同樣的變數名稱。

......

官網還是一如既往的不說人話,短短幾句話就給你介紹完了,也不告訴你這玩意怎麼用,也不告訴你let宣告的變數的值到底是從哪裡來的。我越看越氣,得,官網你不說,我自己找。

先說一個粗略的結論:let宣告的變數是這個template模板的上下文物件中的變數。不然為啥叫模板輸入變數呢。在*ngFor內幕這小節中,我們了解到了其內幕,結構性指令其實就是將宿主元素包裹在一個<ng-template></ng-template>中,然後在這個模板上將*ngFor中的表達式解析成一個個的let模板輸入變數和這個指令需要傳入的值。由於模板中程式碼並不會直接被渲染成視圖,所以一定需要某種方法來讓模板變成視圖。我們的結構性指令就是做這個事的,就是將我們的模板變成視圖。

*ngFor的官方範例程式碼如下:

//解析前的模板
<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">
  ({{i}}) {{hero.name}}
</div>
//angular解析后的模板
<ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById">
  <div [class.odd]="odd">({{i}}) {{hero.name}}</div>
</ng-template>
登入後複製
  • #在此提示一下,所謂的宿主元素就是指令所在的那個元素,像上面的例子中,div就是*ngFor指令的宿主元素。
  • trackBy這個類似vue和react中的key。可以給模板一個標識,使其重新渲染的時候效能開銷降低一些。

然後我們再看官網說的:

  • #let-ilet-odd 變數是透過let i=indexlet odd=odd 來定義的。 Angular 把它們設定為上下文物件中的 indexodd 屬性的目前值。
  • 這裡並沒有指定 let-hero 的上下文屬性。它的來源是隱式的。 Angular 將 let-hero 設定為此上下文中 $implicit 屬性的值, 它是由 NgFor 用目前迭代中的英雄初始化的。

看完這段描述,我們可以得知:angular為這個範本設定了上下文物件。但是我們看不到這個過程,因為這是在ngFor的源碼內部實現的。而這個上下文物件具備indexodd屬性,並且包含一個$implicit(implicit:含蓄的;不直接言明的)的屬性。那我們推論這個上下文物件至少有以下幾個屬性:

{
    $implicit:null,
    index:null,
    odd:null,
}
登入後複製

那么我们声明let变量的本质其实就是声明一个变量获取上下文对象中的同名属性的值let-hero不进行任何赋值的话,hero默认等于$implicit的值。无论是有多少个let-alet-blet-c还是let-me。声明的这个变量的值都等于$implicit的值。而我们进行赋值过的,比如let-i = "index"i的值就等于这个上下文对象中的index属性对应的值。

上下文对象是如何设置的

当我们知道这个上下文对象是什么了,就该想这个上下文对象是怎么设置的了

结构性指令这一节当中,我们跟着官方示例做了一遍这个自定义结构性指令(如果还没有做的话,建议先跟着做一遍)。在UnlessDirective这个指令中,其构造器constructor声明了两个可注入的变量,分别是TemplateRefViewContainerRef。官网给的解释我觉得太过晦涩难懂,我这里给出一下我自己的理解:TemplateRef代表的是宿主元素被包裹之后形成的模板的引用。而ViewContainerRef代表的是一个视图容器的引用。那么问题来了,这个视图容器在哪儿呢?我们在constructor构造器中打印一下ViewContainerRef。打印结果如图:

詳解Angular中的模板輸入變數(let-變數)

然后我们点进去这个comment元素。发现其就是一个注释元素。如图所示:

詳解Angular中的模板輸入變數(let-變數)

其实我也不是很确定这个视图容器到底是不是这个注释元素。但是毋庸置疑的是,视图容器和宿主元素是兄弟关系,紧挨着宿主元素。我们可以使用ViewContainerRef中的createEmbeddedView() 方法(Embedded:嵌入式,内嵌式),将templateRef模板引用传入进去,创建出来一个真实的视图。由于这个视图是被插入到视图容器ViewContainerRef中了,所以又叫内嵌视图。那么这又和我们的上下文对象有什么关系呢?其实createEmbeddedView这个方法不止一个参数,其第二个参数就是给我们的模板设置上下文对象的。API的详情介绍请看createEmbeddedView这个API的详情

詳解Angular中的模板輸入變數(let-變數)

就这样。我们就可以将上下文对象塞入模板中了,这样的话我们也可以直接使用let声明变量的方法来使用这个上下文对象了。

自定义一个简单的类*ngFor指令——appRepeat

那么我们知道是如何设置的了,那么我们就来验证一下是否是对的。接下来,我们仿照ngfor的功能,自己写一个简单的渲染指令。

首先我们定义一个指令:RepeatDirective。代码如下:

@Directive({
  selector: &#39;[appRepeat]&#39;,
})
export class RepeatDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
  ) { }

  @Input() set appRepeatOf(heroesList: string[]) {
    heroesList.forEach((item, index, arr) => {
      this.viewContainer.createEmbeddedView(this.templateRef, {
        //当前条目的默认值
        $implicit: item,
        //可迭代对象的总数
        count: arr.length,
        //当前条目的索引值
        index: index,
        //如果当前条目在可迭代对象中的索引号为偶数则为 true。
        even: index % 2 === 0,
        //如果当前条目在可迭代对象中的索引号为奇数则为 true。
        odd: index % 2 === 1,
      });
    });
  }
}
登入後複製

然后我们将其导入NgModule中,这个过程就省略不写了。然后我们在组件中使用一下这个指令:

@Component({
  selector: &#39;app-structural-likeNgFor-demo&#39;,
  template: `
    <h2 id="原神-版本卡池角色">原神1.5版本卡池角色</h2>
    <h4 id="自定义ngFor-appRepeat">自定义ngFor(appRepeat)</h4>
    <ul>
      <li *appRepeat="let h of heroesList;let i = index;let even = even">
        索引:{{i}} -- {{h}} -- 索引值是否是偶数:{{even.toString()}}
      </li>
    </ul>
    <h4 id="真正的ngFor">真正的ngFor</h4>
    <ul>
      <li *ngFor="let h of heroesList;let i = index;let even = even">
        索引:{{i}} -- {{h}} -- 索引值是否是偶数:{{even.toString()}}
      </li>
    </ul>
  `,
})
export class StructuralLikeNgForDemoComponent {
  public heroesList: string[] = [&#39;钟离&#39;, &#39;烟绯&#39;, &#39;诺艾尔&#39;, &#39;迪奥娜&#39;];
}
登入後複製

在这里需要注意的是指令中的appRepeatOf不是乱写的。在微语法的解析过程中let h of heroesList中的of首先首字母会变成大写的,变成Of。然后在给它加上这个指令的前缀,也就是appRepeat。组合起来就是appRepeatOf了。由它来接收一个可迭代的对象。

最后显示的效果图:

詳解Angular中的模板輸入變數(let-變數)

运行结果的话和*ngFor没有区别。但是功能肯定是欠缺的,如果有能力的小伙伴可以去阅读*ngFor的源码:*ngFor的源码

總結

透過這篇文章,我們知道了let-變數這個範本輸入變數是透過範本的上下文物件中定義並取得值的。然後想要設定上下文物件的話需要透過createEmbeddedView方法的第二個參數來設定。

結語

但是我總覺得了解的還不夠透徹,我總覺得設定範本的上下文物件可能不只是createEmbeddedView 這一種方法,但是我並沒有找到其他的方法。如果各位小夥伴有知道其他的方法可以留言告訴我。

參考資料:

這篇文章靈感來自:Angular 實作一個"repeat" 指令

更多程式相關知識,請訪問:編程視頻! !

以上是詳解Angular中的模板輸入變數(let-變數)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1318
25
PHP教程
1269
29
C# 教程
1248
24
聊聊Angular中的元資料(Metadata)和裝飾器(Decorator) 聊聊Angular中的元資料(Metadata)和裝飾器(Decorator) Feb 28, 2022 am 11:10 AM

這篇文章繼續Angular的學習,帶大家了解Angular中的元數據和裝飾器,簡單了解一下他們的用法,希望對大家有幫助!

如何在Ubuntu 24.04上安裝Angular 如何在Ubuntu 24.04上安裝Angular Mar 23, 2024 pm 12:20 PM

Angular.js是一種可自由存取的JavaScript平台,用於建立動態應用程式。它允許您透過擴展HTML的語法作為模板語言,以快速、清晰地表示應用程式的各個方面。 Angular.js提供了一系列工具,可協助您編寫、更新和測試程式碼。此外,它還提供了許多功能,如路由和表單管理。本指南將討論在Ubuntu24上安裝Angular的方法。首先,您需要安裝Node.js。 Node.js是一個基於ChromeV8引擎的JavaScript運行環境,可讓您在伺服器端執行JavaScript程式碼。要在Ub

一文探究Angular中的服務端渲染(SSR) 一文探究Angular中的服務端渲染(SSR) Dec 27, 2022 pm 07:24 PM

你知道 Angular Universal 嗎?可以幫助網站提供更好的 SEO 支援哦!

淺析angular中怎麼使用monaco-editor 淺析angular中怎麼使用monaco-editor Oct 17, 2022 pm 08:04 PM

angular中怎麼使用monaco-editor?以下這篇文章記錄下最近的一次業務中用到的 m​​onaco-editor 在 angular 中的使用,希望對大家有幫助!

Angular + NG-ZORRO快速開發一個後台系統 Angular + NG-ZORRO快速開發一個後台系統 Apr 21, 2022 am 10:45 AM

這篇文章跟大家分享一個Angular實戰,了解一下angualr 結合 ng-zorro 如何快速開發一個後台系統,希望對大家有幫助!

如何使用PHP和Angular進行前端開發 如何使用PHP和Angular進行前端開發 May 11, 2023 pm 04:04 PM

隨著網路的快速發展,前端開發技術也不斷改進與迭代。 PHP和Angular是兩種廣泛應用於前端開發的技術。 PHP是一種伺服器端腳本語言,可以處理表單、產生動態頁面和管理存取權限等任務。而Angular是一種JavaScript的框架,可以用來開發單一頁面應用程式和建構元件化的網頁應用程式。本篇文章將介紹如何使用PHP和Angular進行前端開發,以及如何將它們

angular學習之詳解狀態管理器NgRx angular學習之詳解狀態管理器NgRx May 25, 2022 am 11:01 AM

這篇文章帶大家深入了解angular的狀態管理器NgRx,介紹一下NgRx的使用方法,希望對大家有幫助!

使用Angular和Node進行基於令牌的身份驗證 使用Angular和Node進行基於令牌的身份驗證 Sep 01, 2023 pm 02:01 PM

身份驗證是任何網路應用程式中最重要的部分之一。本教程討論基於令牌的身份驗證系統以及它們與傳統登入系統的差異。在本教程結束時,您將看到一個用Angular和Node.js編寫的完整工作演示。傳統身份驗證系統在繼續基於令牌的身份驗證系統之前,讓我們先來看看傳統的身份驗證系統。使用者在登入表單中提供使用者名稱和密碼,然後點擊登入。發出請求後,透過查詢資料庫在後端驗證使用者。如果請求有效,則使用從資料庫中獲取的使用者資訊建立會話,然後在回應頭中傳回會話訊息,以便將會話ID儲存在瀏覽器中。提供用於存取應用程式中受

See all articles