装饰器
@Component({selector: 'app-heroes',templateUrl: './heroes.component.html',styleUrls: ['./heroes.component.less'],// 当前组件所需的服务提供商的一个数组。// 在这个例子中,它告诉 Angular 该如何提供一个 HeroService 实例,以获取要显示的英雄列表。providers: [HeroService],// template: '<div class="container">这是一个内联模板</div>'});
模板
HTML
插值与模板表达式
- {{ 1+1 }}是插值表达式
- 1+1是模板表达式
表达式可以调用宿主组件的方法:{{1 + 1 + getVal()}}
表达式上下文
典型的表达式上下文就是这个组件实例
- 表达式的上下文可以包括组件之外的对象。 比如
模板输入变量 (let customer)和模板引用变量(#customerInput) - 表达式中的上下文变量是由
模板变量、指令的上下文变量(如果有)和组件的成员叠加而成的模板语句
绑定
模板绑定是通过 property 和事件来工作的,而不是 attribute。
属性绑定
也不能使用属性 绑定 来调用目标元素上的方法。 如果这个元素触发了事件,可以通过事件绑定来监听它们。 如果必须读取目标元素上的属性或调用它的某个方法,得用另一种技术。 参见 API 参考手册中的 ViewChild 和 ContentChild。
绑定目标
- 元素指令,如[src]
- 属性型指令的属性名,如[ngClass]
-
消除副作用
一般建议是,只绑定数据属性和那些只返回值而不做其它事情的方法。
属性绑定还是插值
建议建立代码风格规则,选择一种形式
- 但数据类型不是字符串时,就必须使用属性绑定了。
<p><img src="{{heroImageUrl}}"> is the <i>interpolated</i> image.</p><p><img [src]="heroImageUrl"> is the <i>property bound</i> image.</p>
attribute, class, style绑定
attribute,对于无法绑定property的例外情况
angular6 中的 property-binding 和 attribute-binding<tr><td [attr.colspan]="1 + 1">One-Two</td></tr><button [attr.aria-label]="actionName">{{actionName}} with Aria</button>
class绑定
// CSS 类绑定 是添加或删除单个类的最佳途径。<li [class.selected]="hero === selectedHero"></li><div class="special" [class.special]="!isSpecial">This one is not so special</div>// 如果badCurly有值会全部覆盖<div class="bad curly special" [class]="badCurly">Bad curly</div>
// 同时添加或移除多个 CSS 类时,NgClass 指令可能是更好的选择<div [ngClass]="currentClasses">[ngClass] binding to the classes property</div>
this.currentClasses = {'saveable': this.canSave,'modified': !this.isUnchanged};
style绑定
// 样式绑定是设置单一样式值的简单方式。<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>
// 如果要同时设置多个内联样式,NgStyle 指令可能是更好的选择。<div [ngStyle]="currentStyles">lyy</div>
this.currentStyles = {'font-style': this.canSave ? 'italic' : 'normal','font-size': this.isSpecial ? '24px' : '12px'};
注意,样式属性命名方法可以用中线命名法,像上面的一样 也可以用驼峰式命名法,如 fontSize。
事件绑定
- 匹配到元素事件或已知指令的输出属性(自定义事件)
- 绑定会通过名叫 $event 的事件对象传递关于此事件的信息
使用 EventEmitter 实现自定义事件
```typescript @Output() deleteRequest = new EventEmitter- ();
delete() { this.deleteRequest.emit(this.item); }
<a name="wEf5C"></a>### 双向绑定虽然 ngModel 是一个有效的 Angular 指令,不过它在默认情况下是不可用的。它属于一个可选模块 FormsModule,你必须自行添加此模块才能使用该指令。<a name="d0ZH2"></a>#### input 非双向绑定```html<input #heroName /><button (click)="add(heroName.value); heroName.value=''">
父子组件双向绑定
<app-sizer [(size)]="fontSizePx"></app-sizer>
表单双向绑定
需模块 FormsModule
你不能把ngModel用到非表单类的原生元素或第三方自定义组件上,除非写一个合适的值访问器,这种技巧超出了本章的范围。
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
展开形式
[(ngModel)] 语法只能设置数据绑定属性。 如果要做更多或者做点不一样的事,也可以写它的展开形式。
<input[ngModel]="currentHero.name"(ngModelChange)="setUppercaseName($event)">
指令(结构型和属性型)
*ngFor
[ngFor](https://angular.cn/api/common/NgForOf) 可以为任何可迭代的 (iterable) 对象重复渲染条目。
<li *ngFor="let hero of heroes; let i=index; trackBy: trackByHeroes"><li *ngFor="let hero of heroes; index as i; trackBy: trackByHeroes">
带 trackBy 的 *ngFor
往组件中添加一个方法,它会返回 NgFor应该追踪的值。 在这里,这个值就是英雄的 id。
即重新请求的数据,只有id变化了的才重新渲染。(注意这只是简单的情况,仅关注id)
<div *ngFor="let item of items; trackBy: trackByItems">({{item.id}}) {{item.name}}</div>
class H {trackByHeroes(index: number, hero: Hero): number { return hero.id; }}
*ngIf
<div *ngIf="selectedHero"></div>
当 selectedHero 为 undefined 时,ngIf 从 DOM 中移除了英雄详情。因此也就不用担心 selectedHero 的绑定了。 当用户选择一个英雄时,selectedHero 也就有了值,并且 ngIf 把英雄的详情放回到 DOM 中。
显示/隐藏的技术对于只有少量子元素的元素是很好用的,但要当心别试图隐藏大型组件树。相比之下,NgIf 则是个更安全的选择。
NgSwitch
<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>
模板引用变量
模板引用变量的作用范围是整个模板。
<input #phone placeholder="phone number"> // #<input ref-address placeholder="home address"> // ref<button (click)="callPhone(phone.value)">Call</button>
不过,指令也可以修改这种行为,让这个值引用到别处,比如它自身。 NgForm 指令就是这么做的。
<form (ngSubmit)="onSubmit(heroForm)" #heroForm="ngForm"><!-- ... --><!-- 这里的 heroForm 实际上是一个 Angular NgForm 指令的引用 --><button type="submit" [disabled]="!heroForm.form.valid">Submit</button></form>
输入输出属性
// 方式2@Component({inputs: ['hero'],outputs: ['deleteRequest']});// 方式1export class HeroDetailComponent {@Input() hero: Hero;@Output() deleteRequest = new EventEmitter<Hero>();}
