Angular
基础知识
使用{{…}}在标签外获取变量 ;
使用*ngFor进行遍历 ;
在属性中使用的变量,使用[]括住属性名 ;
使用*ngIf可以进行判断,决定标签是否显示
使用(…)完成事件的绑定
<div *ngFor =’let 自定义 of 数组变量名 ’>
<!—这时链接的title属性可以接收变量,且属性中的变量不用用{{…}}包含起来-->
<a [title] = “ 自定义.成员名 + ’字符串拼接’ ”>
<p *ngIf =“ 自定义.成员名 “ >
Description: {{ 自定义.成员名 }}
</p>
<!—把 button 的 click 事件绑定到我们替你定义好的 share() 方法上-->
<button (click)="share()"> Share </button>
<h3>{自定义.成员名}</h3>
</div>
手动创建组件
Import { Component } from ‘angular/core’; //引入Component
@Component({ //编写组件内容的装饰器
selector: ‘my-compoent’ //选择器,即自定义组件的标签名
templateUrl: ‘./index.html’ //组件模板的地址,也可以去掉url直接编写内容
styleUrls: ‘./index.css’ //组件样式的地址,也可以去掉url直接编写内容
})
注意,这个@ Component依然是修饰class的注解,不是单独使用
父子组件之间的数据通信
子组件组件
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-product-alerts',
template: '
<p *ngIf="product.price > 700"> ]\
<button>Notify Me</button> \
</p>
',
styleUrls: ['./product-alerts.component.css'] })
export class ProductAlertsComponent implements OnInit {
@Input() product;
constructor() { }
ngOnInit() { }
}
通过属性绑定把当前商品作为输入传给组件
<!--[product]是子组件中的属性,而”product”是父组件传入的值 -->
<app-product-alerts [product]="product">
</app-product-alerts>
理解视图
组件和其关联模板定义了一个视图(可以理解为组件模板的实例化,代码内容在惠html文件中)。视图中各个元素的属性可以动态修改以响应用户的操作,而这些元素的结构(DOM的数量或顺序)则不能。你可以通过在它们的视图容器中插入、移动或移除内嵌视图来修改这些元素的结构。
例子:地址 www.space.com/list/#/page1 用#标注了的地址数据,浏览器不解析,实际的资源地址依旧是,地址 /list。因此通过后面的数据,更改单页网页的视图,在同一个网页地址中获得不同的显示效果
路由
路由器能让你在不同的视图中显示产品的详情,每个产品都有自己的 URL。当用户执行应用任务时,路由器可以从一个视图导航到另一个视图(但在同一个页面)。比如:
生命周期事件
钩子函数,即组件某一时段完成某个生命周期后自动执行的函数,可以通过实现钩子接口实现某个生命周期要做的事情
peek-a-boo.component.ts
@Directive( {selector:[appSpy]}) // Directive注解,表明该类是一个属性指令
export class MyCompoent implements OnInit{ //实现OnInit接口,实现ngOnInit()方法
ngOnInit() { this.logger.log(‘实现了初始化OnInit接口’); }
}
使用方式
<div appSpy class="heroes"> {{hero}} </div>
使用 ngOnInit() 方法执行以下初始化任务。
使用ngOnDestroy() 方法执行清理任务
使用ngOnChanges方法检测输入属性变化
视图封装模式
组件的 CSS 样式被封装进了自己的视图中,而不会影响到应用程序的其它部分。
组件之间的交互
@Input允许父组件更新子组件中的数据
子组件中用@Input修饰属性,表示该属性可以从父组件中获取值
import { Component } from '@angular/core';
import { Hero } from './hero';
@Component({
selector: 'app-hero-child',
template: ` <h3>{{ children_hero.name}} </h3> `
})
export class ChildComponent {
@Input() children_hero: Hero;//表示这个变量可以接收父组件的数据
}
父组件代码
import { Component } from '@angular/core';
import { HEROES } from './hero';
@Component({
selector: 'app-hero-parent',
//模板中使用了子组件,而子组件属性children_hero被父组件的hero赋值
template: ` <h2> {{heroes.length}} heroes</h2> \
<app-hero-child *ngFor="let hero of heroes"\
[children_hero]="hero" >\
</app-hero-child> ` })
export class HeroParentComponent {
heroes = HEROES;
}
使用一个输入属性的 set,以拦截父组件中值的变化,并采取行动。
export class NameChildComponent {
//get修饰一个name函数,自动创建了一个name属性,子组件可直接使用[name]
@Input() get name(): string { return this._name; }
// set修饰一个name函数,则组件name属性发生变动时,自动调用set name()函数
set name(name: string) {
this._name = (name && name.trim()) || '<no name set>';
}
private _name = ''; //_name只是一个临时变量,用于返回值
}
继承@ OnChanges实现ngOnChanges()来截听输入属性值的变化,注意之监听@Input修饰的数据
父组件监听子组件事件
子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。
………
@Component({
selector: 'app-voter',
template: ` <h4>{{name}}</h4>
<button (click)="vote(true)"[disabled]="didVote">Agree</button>
<button (click)="vote(false)"[disabled]="didVote">Disagree</button> `
})
export class VoterComponent {
@Input() name: string;
@Output() voted = new EventEmitter<boolean>();
didVote = false;
//使用voted属性的emits方法向父组件发送数据
vote(agreed: boolean) {
this.voted.emit(agreed);
this.didVote = true;
} }
父组件绑定了一个事件处理器(onVoted()),用来响应子组件的事件($event)
@Component({
selector: 'app-vote-taker',
template: ` <h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
<app-voter *ngFor="let voter of voters" [name]="voter"
//使用()完成事件的绑定
(voted)="onVoted($event)">
</app-voter> ` })
export class VoteTakerComponent {
agreed = 0;
disagreed = 0;
voters = ['Narco', 'Celeritas', 'Bombasto'];
onVoted(agreed: boolean) {
agreed ? this.agreed++ : this.disagreed++;
} }
父组件与子组件通过本地变量互动
父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法。
子组件
……
export class CountdownTimerComponent implements OnDestroy {
var1= 0;
var2 = '';
ngOnDestroy() { …… }
start() { …… }
stop() { …… }
}
父组件要想使用子组件中的内容时,使用#代表模板本地变量。,可以理解为子组件的别名
import { Component } from '@angular/core';
import { CountdownTimerComponent } from './countdown-timer.component'; @Component({
selector: 'app-countdown-parent-lv',
template: ` <h3>Countdown to Liftoff (via local variable)</h3>
<button (click)="timer.start()">Start</button>
<button (click)="timer.stop()">Stop</button>
<div class="seconds">{{timer.seconds}}</div>
<app-countdown-timer #timer></app-countdown-timer> `,
styleUrls: ['../assets/demo.css'] })
export class CountdownLocalVarParentComponent { }
父组件调用@ViewChild()
以上方法是父组件的模板中使用了子组件的属性方法,但是
如果父组件的类需要读取子组件的属性值或调用子组件的方法,就不能使用本地变量方法。
当父组件类需要这种访问时,可以把子组件作为 ViewChild,注入到父组件里面。
@Component({
selector: 'app-countdown-parent-vc',
template: ` <h3>Countdown to Liftoff (via ViewChild)</h3>
<button (click)="start()">Start</button>
<button (click)="stop()">Stop</button>
<div class="seconds">{{ seconds() }}</div>
<app-countdown-timer></app-countdown-timer> `,
styleUrls: ['../assets/demo.css'] })
export class CountdownViewChildParentComponent implements AfterViewInit{ @ViewChild(CountdownTimerComponent) private timerComponent: CountdownTimerComponent; seconds() { return 0; } ngAfterViewInit() { // Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ... // but wait a tick first to avoid one-time devMode // unidirectional-data-flow-violation error setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0); } start() { this.timerComponent.start(); } stop() { this.timerComponent.stop(); } }
父子组件通过服务来通讯
样式
:host 伪类选择器,用来选择宿主组件中的元素
:host { display: block; border: 1px solid black; }
指令
使用 ComponentFactoryResolver 来动态添加组件。
在添加组件之前,要定义一个锚点来告诉 Angular 要把组件插入到什么地方
模板
管道
自定义管道
用@Pipe修饰类
@Pipe({name: 'exponentialStrength'})
<app-countdown-timer>