2020国庆节Angular structual指令学习笔记
修改用户页面完成后,点击“确认”按钮,界面没有任何反应,用户也不知道修改成功与否。
只有点击f12打开Chrome开发者工具,观察eduser API的响应:
在response里看到status code为0,interpret字段为“修改成功”,才知道确认按钮点击之后修改确实生效了。这个bebavior对普通老百姓很不友好。
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 that surrounds the host element and its descendants. Each structural directive does something different with that template.
这里的星号实际上是一个语法糖,后面的ngIf称之为microsyntax,即微语法。Angular会把进行解糖操作,替换成传统的实现。值得一提的是,后者也不会出现在最后生成的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 element where it became a property binding,[ngIf].
- The rest of the , including its class attribute, moved inside the element.
Angular consumed the content during its actual rendering and replaced the with a diagnostic comment.
Angular渲染时,将替换成用于诊断目的的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.
使用微语法(一个字符串)配置结构性指令。微语法解析器把这个字符串里的内容解析成的属性:
- 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 - 二者有各自的命名空间。
里面包含的元素不会出现在最后的HTML页面里:
为什么要使用ng-template, 而不重用div,span这些HTML原生的container元素?
Introducing another container element—typically a or —to group the elements under a single root is usually harmless. Usually … but not always.
如果应用程序里恰巧有css样式施加到或者
上,此时再用二者作为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 element requires children. You can’t wrap the options in a conditional or a .
还有一种情况,某些html元素要求其子元素必须是一种特殊的类型,比如的子元素必须是, 二者中间不能再引入
或者等中间层级。
像下图这种设计,最后是看不到下拉菜单的:
<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 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 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解析器能够识别这个语法元素,后者并不是一夜指令,也非Component,class或者interface. 和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 satisfies a similar need in Angular templates.
- 【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络AlexNet
- 黄荣奎:如何快速、便捷开发小程序
- 熊普江: BGP网络架构助力开发者快速构建、优化业务
- 唐良:云端架构给电商行业带来创新力
- 邹方明:看腾讯云如何架构海量存储系统
- 王之捷:AI智能云端架构大幅提升智能语音识别能力
- 精彩大放送 | 腾讯云:容器架构向无服务架构的演进
- Python 数据分析学习笔记
- 如何用Fiddler抓取https
- 人工智能与大数据结合,帮助降低自杀率
- “多态”的数据库连接池实现
- ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider
- 用js代码理解区块链,最简版本
- 谈谈IE针对Ajax请求结果的缓存
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java8实战——通过行为参数化传递代码 顶
- Angular component的一个例子
- 初识mybatis中的缓存
- 【卷积神经网络结构专题】ResNet及其变体的结构梳理、有效性分析
- Steganographer:能帮助在图片中隐藏数据的Python隐写工具
- 内网横向移动:Kerberos认证与(哈希)票据传递攻击
- 诺禾致源linux下数据下载
- 技巧 | OpenCV中如何绘制与填充多边形
- Swift guard
- PyTorch实现TPU版本CNN模型
- 使用NLP检测和对抗AI假新闻
- kallisto --genomebam报错解决(GTF文件的坑)
- linux查找文件
- TCP 协议面试灵魂 12 问,问到你怀疑人生!
- 方差分析简介(结合COVID-19案例)