2020国庆节 Angular structual 指令学习笔记(<ng-template>) 包含语法糖解糖过程
Structural directives are responsible for HTML layout. They shape or reshape the DOM’s structure, typically by adding, removing, or manipulating elements.
structure directive負責HTML布局,組成或者改變DOM結構,在結構中添加移除或者控制其他HTML元素。
As with other directives, you apply a structural directive to a host element. The directive then does whatever it’s supposed to do with that host element and its descendants.
structural指令也需要施加到host元素上,指令會對host和其子元素施加影響。
一個例子:
<div *ngIf=“hero” class=“name”>{{hero.name}}
the asterisk (*) is a convenience notation and the string is a microsyntax rather than the usual template expression. Angular desugars this notation into a marked-up <ng-template> that surrounds the host element and its descendants. Each structural directive does something different with that template.
這里的星號實際上是一個語法糖,后面的ngIf稱之為microsyntax,即微語法。Angular會把進行解糖操作,替換成傳統的<ng-template>實現。值得一提的是,后者也不會出現在最后生成的html代碼里。
注意命名規范:
Throughout this guide, you’ll see a directive spelled in both UpperCamelCase and lowerCamelCase. Already you’ve seen NgIf and ngIf. There’s a reason. NgIf refers to the directive class; ngIf refers to the directive’s attribute name.
NgIf是結構化指令的實現class,ngif是指令的屬性名,應用在HTML代碼里。
除了structural指令外,Angular常用的還有Component指令和屬性指令兩種。
- A component manages a region of HTML in the manner of a native HTML element. Technically it’s a directive with a template.
- An attribute directive changes the appearance or behavior of an element, component, or another directive. For example, the built-in NgStyle directive changes several element styles at the same time.
You can apply many attribute directives to one host element. You can only apply one structural directive to a host element.
structural指令和host元素是1:1關系,attribute指令和host元素可以是N:1關系。
NgIf takes a boolean expression and makes an entire chunk of the DOM appear or disappear.
<p *ngIf="true">Expression is true and ngIf is true.This paragraph is in the DOM. </p> <p *ngIf="false">Expression is false and ngIf is false.This paragraph is not in the DOM. </p>運行時渲染出來的html里面,根本沒有*ngIf="false"的html元素:
ngif語法糖的解糖過程
原始代碼:
<div *ngIf="hero" class="name">{{hero.name}}</div>解糖之后:
<ng-template [ngIf]="hero"><div class="name">{{hero.name}}</div> </ng-template>- The *ngIf directive moved to the <ng-template> element where it became a property binding,[ngIf].
- The rest of the <div>, including its class attribute, moved inside the <ng-template> element.
Angular consumed the <ng-template> content during its actual rendering and replaced the <ng-template> with a diagnostic comment.
Angular渲染時,將<ng-template>替換成用于診斷目的的ng-reflect-ng-if.
ngfor的解糖過程
原始代碼:
<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">({{i}}) {{hero.name}} </div>解糖之后:
<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>At minimum NgFor needs a looping variable (let hero) and a list (heroes).
NgFor至少需要一個列表(heroes)和展開這個列表的變量(let hero).
什么是微語法 Microsyntax
The Angular microsyntax lets you configure a directive in a compact, friendly string.
使用微語法(一個字符串)配置結構性指令。微語法解析器把這個字符串里的內容解析成<ng-template>的屬性:
-
The parser translates let hero, let i, and let odd into variables named let-hero, let-i, and let-odd.
-
As the NgFor directive loops through the list, it sets and resets properties of its own context object. These properties can include, but aren’t limited to, index, odd, and a special property named $implicit.
NgFor遍歷list,在每次循環過程體內部設置它自己上下文對象的屬性,比如index,odd和$implicit.
Template input variable
A template input variable is a variable whose value you can reference within a single instance of the template. 可以在模板的某一個具體實例內被使用。
You declare a template reference variable by prefixing the variable name with # (#var). 通過#定義模板引用變量,指向它依附于的元素,組件或指令。整個模板內都可以訪問。
A reference variable refers to its attached element, component or directive. It can be accessed anywhere in the entire template.
Template input and reference variable names have their own namespaces. The hero in let hero is never the same variable as the hero declared as #hero - 二者有各自的命名空間。
<ng-template>里面包含的元素不會出現在最后的HTML頁面里:
為什么要使用ng-template, 而不重用div,span這些HTML原生的container元素?
Introducing another container element—typically a <span> or <div>—to group the elements under a single root is usually harmless. Usually … but not always.
如果應用程序里恰巧有css樣式施加到<span>或者<div>上,此時再用二者作為structural指令的host元素就不太合適了,比如下面這個例子:
<p>I turned the corner<span *ngIf="hero">and saw {{hero.name}}. I waved</span>and continued on my way. </p>如果正好有css樣式施加到span上:
p span { color: red; font-size: 70%; }最后的布局就很怪異:
some HTML elements require all immediate children to be of a specific type. For example, the <select> element requires <option> children. You can’t wrap the options in a conditional <div> or a <span>.
還有一種情況,某些html元素要求其子元素必須是一種特殊的類型,比如<select>的子元素必須是<option>, 二者中間不能再引入<div>或者<span>等中間層級。
像下圖這種設計,最后是看不到下拉菜單的:
<div>Pick your favorite hero(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>) </div> <select [(ngModel)]="hero"><span *ngFor="let h of heroes"><span *ngIf="showSad || h.emotion !== 'sad'"><option [ngValue]="h">{{h.name}} ({{h.emotion}})</option></span></span> </select>解決方案是采用ng-container:
The Angular <ng-container> is a grouping element that doesn’t interfere with styles or layout because Angular doesn’t put it in the DOM.
是一種grouping element,不會干預HTML正常的布局和樣式,因為Angular不會將其渲染到最終的HTML中去。
<div>Pick your favorite hero(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>) </div> <select [(ngModel)]="hero"><ng-container *ngFor="let h of heroes"><ng-container *ngIf="showSad || h.emotion !== 'sad'"><option [ngValue]="h">{{h.name}} ({{h.emotion}})</option></ng-container></ng-container> </select>注意,要使用ngModel指令,必須先import FormsModule.
The <ng-container> is a syntax element recognized by the Angular parser. It’s not a directive, component, class, or interface. It’s more like the curly braces in a JavaScript if-block.
Angular解析器能夠識別<ng-container>這個語法元素,后者并不是一個指令,也非Component,class或者interface. <ng-container>和JavaScript里的if block很類似:
if (someCondition) {statement1;statement2;statement3; }Without those braces, JavaScript would only execute the first statement when you intend to conditionally execute all of them as a single block. The <ng-container> satisfies a similar need in Angular templates.
要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":
總結
以上是生活随笔為你收集整理的2020国庆节 Angular structual 指令学习笔记(<ng-template>) 包含语法糖解糖过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 发现四川科技馆在线网站修改用户设置页面的
- 下一篇: tensorflow学习笔记:卷积神经网