Angular 8 组件
栏目: JavaScript · 发布时间: 6年前
内容简介:插值法从数据流向划分为
创建一个组件
- 独立模板
ng g c user-list
- 内联模板
ng g c user-list -it
显示值
插值法
{{}}
绑定值
从数据流向划分为 3 种:
- 数据源 -> Template
- {{expression}}
- [target]="expression"
- bind-target="expression"
- Template -> 数据源
- (target)="statement"
- on-target="statement"
- Template <-> 数据源
- [(target)]="expression"
- bindon-target="expression"
绑定理解的误区
<button [disabled]="isUnchanged">Save</button>
这并不是将 isUnchanged 的值绑定到了 button 的 disabled attribute 上,而是设置在 该 DOM 元素的 property disabled 上。
HTML attribute 与 DOM property 的对比
- HTML attribute 用来初始化 DOM property
- attribute 一旦设置则不可修改,property 可以修改
- attribute 可以理解为初始值,property 理解为当前值
- attribute 与 property 并不是完全对应的
模板绑定是通过 property 和 event 来工作的,而不是 attribte
绑定目标
绑定的目标可以是 property、event、property+event(双向)
属性绑定(property)
-
[property]形式
<img [src]="url"> -
bind-property形式
<img bind-src="url">
不应该绑定一个会修改其他任何值的表达式(属性、函数),这可能会导致意料之外的问题
[hero]="currentHero" 与 hero="currentHero" 是不同的
- [hero]= 将 currentHero 表达式 绑定到 hero property
- hero= 将 currentHero 字面值 赋予 hero attribute
在绑定字符串类型值的时候 src="{{url}}" 等价于 [src]="url"
attribute 绑定
也写特殊的元素的 DOM 中并没有 property 可供绑定,例如 <td colspan="{{ 1 + 1}}"></td>
元素 td 只有 colspan attribute,而没有其对应的 property,这时候就只能使用 attribute bind。
使用 attr.
绑定 attribute,例如:
<td [attr.colspan]="1 + 1"></td>
css 绑定
- 指定类名
[class.myClass]="expression",表达式为真,添加类,反之移除。
- 覆盖 attribute
[class]="expression" 表达式应该返回一个包含类名的字符串。
- NgClass
[ngClass]="{ 'myClass1': true, 'myClass2': isClass2 }"
style 绑定
- stye.style-property
<span [style.color]="fontColor">字体颜色</span>
- NgStyle
[ngStyle]="{ 'font-color': '#333', 'font-weight': '700' }"
event 绑定
- (event)
<button (click)="onClick()">click</button>
- on-event
<button (click)="onClick()">click</button>
$event
通常,在 angular 中,通过 $event事件对象
传递事件信息 ,例如这样:
<input [value]="name" (input)="name=$event.target.value">
这其实就相当于一个 双向绑定
啦。
EventEmitter
通过 EventEmitter 可以自定义事件,例如:
假设我们有一个对话框组件,他有 ok 和 cancel 两个按钮:
app-dialog
// html...
<button (click)="ok()"></button>
<button (click)="cancel()"></button>
// ts...
@Output('onConfirm') confirmEvent = new EventEmitter<any>();
@Output('onCancel') cancelEvent = new EventEmitter<any>();
public ok():void {
this.confirmEvent.emit("确认");
}
public cancel():void {
this.cancelEvent.emit("取消");
}
调用方
<app-dialog (onConfirm)="func1($event)" (onCancel)="func2($event)"></app-dialog>
$event 就是 emit 传递过来的值
双向绑定
使用 ngModel
指令需要 FormsModule
,所以需要提前将 FormsModule 添加到 imports 当中。
双向绑定就是 属性绑定与事件绑定 同时修饰同一个 property,至少 bey 是这么理解的。
假设我们有一个组件,他接受一个叫做 value 的 property,并且对外提供了一个 value 的 change 事件,那么可以这么写到:
<app-value [value]="myvalue" (onValueChange)="myvalue=$event">
angular 觉得这样写挺麻烦的,于是搞了一个 语法糖
,结果语句就变成了这样:
<app-value [(value)]="myvalue">
指令
指令分为两种: 属性型指令 和 结构型指令 。
内置属性型指令
属性型指令一般用来处理 property、attribute、event。例如:NgClass、NgStyle、NgModel。
ngModel 指令通过自己的输入属性 ngModel 和输出属性 ngModelChange 实现双向绑定,简化之后的 语法糖
就是 [(ngModel)]。
内置结构型指令
结构型指令通常会改变 DOM 结构;例如 NgIf、NgSwitch、NgForOf
ngIf 与 [style.hidden] 是不同的,这与 Vue 的 v-if 与 v-show 类似。 ngIf 会从 DOM 移除元素,而 [style.hidden] 仅仅隐藏元素。
1. 微语法
模板输入变量
*ngFor="let hero of heroes" [hero]="hero",let 关键字创建了一个叫做 hero 的 模板输入变量 。他的作用域包括宿主元素和其子元素。
2. *ngFor 索引
*ngFor="let hero of heroes; let i=index"
3. *ngFor trackBy
trackBy 用来告诉 *ngFor 如何避免不应该的性能消耗(避免重复的渲染没有变化的项)
使用 trackBy 需要告诉他需要追踪的值,例如:
<div *ngFor="let hero of heroes; trackBy: trackByHeroes">
({{hero.id}}) {{hero.name}}
</div>
//...
trackByHeroes(index: number, hero: Hero): number { return hero.id; }
只要 id 没有发生变化,DOM 就不会重复劳动。
4. NgSwitch
实际上 NgSwitch 包括 3 个指令:
- NgSwitch
- NgSwitchCase
- NgSwitchDefault
用法:
<div [ngSwitch]="currentHero.emotion"> <app-happy-hero *ngSwitchCase="'happy'" [hero]="currentHero"></app-happy-hero> <app-sad-hero *ngSwitchCase="'sad'" [hero]="currentHero"></app-sad-hero> <app-confused-hero *ngSwitchCase="'confused'" [hero]="currentHero"></app-confused-hero> <app-unknown-hero *ngSwitchDefault [hero]="currentHero"></app-unknown-hero> </div>
NgSwitch 是一个 属性指令,他只修改了行为,没有修改结构,所以不需要 *
5. 模板引用变量
语法:
#var 或 ref-var
模板引用变量通常用来引用模板中的某个 DOM
或 Angular组件
或 指令
或 Web Component
。
模板引用变量的作用域是本模板全局。
- 引用 input 元素
<input #phone placeholder="phone number">
- 引用 ngForm 指令
<form (ngSubmit)="onSubmit(heroForm)" #heroForm="ngForm">
<div class="form-group">
<label for="name">Name
<input class="form-control" name="name" required [(ngModel)]="hero.name">
</label>
</div>
<button type="submit" [disabled]="!heroForm.form.valid">Submit</button>
</form>
<div [hidden]="!heroForm.form.valid">
{{submitMessage}}
</div>
| 对比 | 模板引用变量 | 模板输入变量 |
|---|---|---|
| 声明方式 | #var/ref-var | let var |
| 作用域 | 整个模板 | 宿主、子元素 |
输入输出属性
1. 输入属性
带有 @Input
装饰器的 可设置属性
,一般用于 属性绑定
。
@Input('width'),本组件接受一个叫做 width 的属性绑定。例如: <app-component [width]="width"></app-component>
2. 输出属性
带有 @Output
装饰器的 可观察对象
属性,一般用于 输出事件
。
@Output('onClick') clicks = new EventEmitter<string>();
对外提供一个可供绑定的名为 onClick
的事件,该事件的参数是一个 string
。
模板表达式操作符
1. 管道操作符(|)
管道是一个函数,适合在模板表达式中,处理包括:数据显示格式、过滤、 排序 这样的操作;该函数接受一个输入值,返回结果。
一般用法
<div>Hello {{world | uppercase}}</div>
管道函数可以是连续的使用:
<div>Hello {{wORld | lowercase | uppercase}}</div>
传参:
<div>Birthdate: {{currentHero?.birthdate | date:'longDate'}}</div>
2. 安全导航操作符(?.)
观看该案例:
<span>{{person.name}}</span>
当 person 为 undefined 时,该代码会报错。修改为如下后不会报错:
<span>{{person?.name}}</span>
3. 非空断言操作符(!)
{{person!.name}}
只有在开启了 TypeScript 严格空值检查时,才会用到。
类型转换函数 $any
当表达式无法检测出某个对象包含指定的字段(属性)时,可以使用 $any 让其不进行 TypeScript 的类型编译。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- React 组件模式-有状态组件 x 无状态组件、容器组件 x 展示组件、高阶组件 x 渲染回调(函数作为子组件)
- Serverless 组件开发尝试:全局变量组件和单独部署组件
- angular自定义组件-UI组件篇-switch组件
- React Hooks 源码解析(一):类组件、函数组件、纯组件
- Vue动态组件和异步组件
- Vue 动态组件 & 异步组件原理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ajax Design Patterns
Michael Mahemoff / O'Reilly Media / 2006-06-29 / USD 44.99
Ajax, or Asynchronous JavaScript and XML, exploded onto the scene in the spring of 2005 and remains the hottest story among web developers. With its rich combination of technologies, Ajax provides a s......一起来看看 《Ajax Design Patterns》 这本书的介绍吧!