Angular2 模板语法
##插值表达式
{{...}}
<p>My name is {{user.name}}</p>
<h3>
{{title}}
<img src="{{heroImageUrl}}" style="height:30px">
</h3>
<!-- "The sum of 1 + 1 is 2" -->
<p>The sum of 1 + 1 is {{1 + 1}}</p>
<!-- "The sum of 1 + 1 is not 4" -->
<p>The sum of 1 + 1 is not {{1 + 1 + getVal()}}</p>
模板表达式
模板表达式产生一个值
Angular 执行这个表达式,并把它赋值给绑定目标的属性,这个绑定目标可能是 HTML 元素、组件或指令。
编写模板表达式所用的语言看起来很像 JavaScript。 很多 JavaScript 表达式也是合法的模板表达式,但不是全部JavaScript 中那些具有或可能引发副作用的表达式是被禁止的,包括:
-
new`运算符
-
使用
;
或,
的链式表达式 -
自增或自减操作符 (
++
和--
) -
赋值 (
=
,+=
,-=
, …)和 JavaScript语法的其它显著不同地方:
-
不支持位运算
|
和&
-
具有新的模板表达式运算符,比如
|
和?.
表达式上下文
典型的表达式上下文就是这个组件实例
<!--title和引号中的isUnchanged所引用的都是Component中的属性。--> {{title}} <span [hidden]="isUnchanged">changed</span>
表达式的上下文可以包括组件之外的对象
<!--模板输入变量 (let hero)和模板引用变量(#heroInput)就是备选的上下文对象之一。--> <div *ngFor="let hero of heroes">{{hero.name}}</div> <input #heroInput> {{heroInput.value}}
-
Expression guidelines(表达式指南)
-
No visible side effects
-
Quick execution
-
Simplicity
-
Idempotence
-
绑定语法
绑定类型
绑定的类型可以根据数据流的方向分成三类: 从数据源到视图、从视图到数据源以及双向的从视图到数据源再到视图。
语法 | 数据方向 | 绑定类型 |
---|---|---|
{{expression}} [target]=“expression” bind-target=“expression” | 从数据源到视图目标(单向) | 插值表达式、Property Attribute类 、样式 |
(target)=“statement” on-target=“statement” | 从视图目标到数据源(单向) | 事件 |
[(target)]=“expression” bind-targe=“expression” | 双向 | 双向 |
绑定目标
属性绑定
<img [src]="heroImageUrl">
<button [disabled]="isUnchanged">Cancel is disabled</button>
<div [ngClass]="classes">[ngClass] binding to the classes property</div>
设置自定义组件的模型属性(这是父子组件之间通讯的重要途径):
<hero-detail [hero]="currentHero"></hero-detail>
属性绑定与插值绑定都可以选择,没有技术上的理由证明哪种形式更好
在渲染视图之前,Angular 把这些插值表达式翻译成相应的属性绑定
<!--做的事情完全相同-->
<p><img src="{{heroImageUrl}}"> is the <i>interpolated</i> image.</p>
<p><img [src]="heroImageUrl"> is the <i>property bound</i> image.</p>
<p><span>"{{title}}" is the <i>interpolated</i> title.</span></p>
<p>"<span [innerHTML]="title"></span>" is the <i>property bound</i> title.</p>
数据类型不是字符串时,就必须使用属性绑定了
attribute、class和style绑定
attribute
**因为当元素没有属性可绑的时候,就必须使用 attribute 绑定**css
<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
css
<!-- reset/override all class names with a binding -->
<div class="bad curly special"
[class]="badCurly">Bad curly
</div>
```
```html
<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>
<!-- binding to `class.special` trumps the class attribute -->
<div class="special"
[class.special]="!isSpecial">This one is not so special
</div>
style
<button [style.color]="isSpecial ? 'red': 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>
<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>
> 注意,*样式属性*命名方法可以用[中线命名法](https://angular.cn/docs/ts/latest/guide/glossary.html#dash-case),像上面的一样 也可以用[驼峰式命名法](https://angular.cn/docs/ts/latest/guide/glossary.html#camelcase),如`fontSize`
> 我们通常更喜欢使用 [NgStyle指令](https://angular.cn/docs/ts/latest/guide/template-syntax.html#ngStyle)来同时设置多个内联样式
事件绑定
目标事件
<button (click)="onSave()">Save</button>
<button on-click="onSave()">On Save</button>
<!-- `myClick` is an event on the custom `ClickDirective` -->
<div (myClick)="clickMessage=$event" clickable>click with myClick</div>
$event* 和事件处理语句
在事件绑定中,Angular 会为目标事件设置事件处理器。
当事件发生时,这个处理器会执行模板语句。
典型的模板语句通常涉及到响应事件执行动作的接收器,例如从 HTML 控件中取得值,并存入模型。
绑定会通过名叫$event的事件对象传递关于此事件的信息(包括数据值)。
事件对象的形态取决于目标事件。如果目标事件是原生 DOM 元素事件, $event
就是 DOM事件对象,它有像target
和target.value
这样的属性。
<input [value]="currentHero.name"
(input)="currentHero.name=$event.target.value" >
使用 EventEmitter 实现自定义事件
template: `
<div>
<img src="{{heroImageUrl}}">
<span [style.text-decoration]="lineThrough">
{{prefix}} {{hero?.name}}
</span>
<button (click)="delete()">Delete</button>
</div>`
...
// This component make a request but it can't actually delete a hero.
deleteRequest = new EventEmitter<Hero>();
delete() {
this.deleteRequest.emit(this.hero);
}
<hero-detail (deleteRequest)="deleteHero($event)" [hero]="currentHero"></hero-detail>