EventEmitterHTTPAsync 管道路由器 (router)響應式表單 (reactive forms)參考文獻javascript
Angular 使用可觀察對象做爲處理各類經常使用異步操做的接口。好比:css
EventEmitter
類派生自 Observable
。Angular 提供了一個 EventEmitter
類,它用來經過組件的 @Output()
裝飾器 發送一些值。EventEmitter
擴展了 RxJS Subject
,並添加了一個 emit()
方法,這樣它就能夠發送任意值了。當你調用 emit()
時,就會把所發送的值傳給訂閱上來的觀察者的 next()
方法。 咱們來查看一下該類的定義:html
export declare class EventEmitter<T extends any> extends Subject<T> {
/**
* Creates an instance of this class that can
* deliver events synchronously or asynchronously.
*
* @param isAsync When true, deliver events asynchronously.
*
*/
constructor(isAsync?: boolean);
/**
* 發出包含給定值的事件。
*/
emit(value?: T): void;
/**
*註冊此實例發出的事件的處理程序。
*/
subscribe(generatorOrNext?: any, error?: any, complete?: any): Subscription;
}
複製代碼
EventEmitter 與指令@Output 一塊兒在組件中使用以同步或異步方式發送自定義事件,並經過訂閱實例來註冊這些事件的處理程序。 java
接下來咱們演示一個案例,在組件之間傳遞數據。react
子組件 zippy.component.ts
web
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-zippy',
templateUrl: '
<div class="zippy">
<div (click)="toggle()">點擊該文本</div>
<div [hidden]="visible">
<ng-content></ng-content>
</div>
</div>
'
})
export class ZippyComponent implements OnInit {
visible = true;
// tslint:disable-next-line: no-output-native
@Output() open = new EventEmitter<any>();
// tslint:disable-next-line: no-output-native
@Output() close = new EventEmitter<any>();
constructor() { }
ngOnInit(): void {
}
toggle() {
this.visible = !this.visible;
if (this.visible) {
this.close.emit('關閉');
} else {
this.open.emit('打開');
this.open.subscribe((data) => {
console.log('open subscribe:' + data);
});
}
}
}
複製代碼
父組件 home4.component.ts
api
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-home4',
templateUrl: '
<app-zippy (open)="onOpen($event)" (close)="onClose($event)">我是home組件的內容</app-zippy>
'
})
export class Home4Component implements OnInit {
constructor() { }
ngOnInit(): void {
}
onOpen(e) {
console.log(e);
}
onClose(e) {
console.log(e);
}
}
複製代碼
運行項目,在頁面上點擊文本內容,注意觀察控制檯輸出的內容。以下圖所示:服務器
上文中關於 ng-content
標籤的使用,感興趣的朋友能夠去閱讀一下:Angular開發實踐(八): 使用ng-content進行組件內容投射app
Angular 的 HttpClient
從 HTTP 方法調用中返回了可觀察對象。例如,http.get(‘/api’)
就會返回可觀察對象。相對於基於承諾(Promise)的 HTTP API,它有一系列優勢:異步
.then()
調用同樣)。反之,你能夠使用一系列操做符來按需轉換這些值。unsubscribe()
方法來取消的。關於講解數據交互那一部份內容時,對於 get、post 請求都有測試案例,如今回頭看當時比較疑惑的內容,如今就豁然開朗了。
AsyncPipe 會訂閱一個可觀察對象或承諾,並返回其發出的最後一個值。當發出新值時,該管道就會把這個組件標記爲須要進行變動檢查的(譯註:所以可能致使刷新界面)。
下面的例子把 time
這個可觀察對象綁定到了組件的視圖中。這個可觀察對象會不斷使用當前時間更新組件的視圖。
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
selector: 'app-asyncpipe',
templateUrl: '
<div><code>observable|async</code>:
Time: {{ time | async }}</div>
'
})
export class AsyncpipeComponent implements OnInit {
time: Observable<any>;
constructor() { }
ngOnInit(): void {
this.time = new Observable(observer => {
setInterval(() => {
observer.next(new Date().toString());
}, 1000);
});
}
}
複製代碼
這樣寫就至關於訂閱了 time,會實時接收 next 過來的值,Observable 定義如上,用來逐秒打印時間,頁面接收的值類型爲 Observable。
頁面測試效果:
observable|async: Time: Tue Apr 14 2020 09:39:46 GMT+0800 (中國標準時間)
複製代碼
如果要接收 object 對象,須要這樣取值。
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
selector: 'app-asyncpipe',
templateUrl: '
<ng-container *ngIf="time2 |async as tim">
<div>
{{tim.date}}---{{tim.time}}
</div>
</ng-container>
'
})
export class AsyncpipeComponent implements OnInit {
time2: Observable<any>;
constructor() { }
ngOnInit(): void {
this.time2 = new Observable(observer => {
setInterval(() => {
const dd = new Date();
observer.next({ date: dd.toString(), time: dd.toTimeString() });
}, 1000);
});
}
}
複製代碼
頁面測試結果:
Tue Apr 14 2020 09:49:38 GMT+0800 (中國標準時間)---09:49:38 GMT+0800 (中國標準時間)
複製代碼
Router.events
以可觀察對象的形式提供了其事件。 你能夠使用 RxJS 中的 filter()
操做符來找到感興趣的事件,而且訂閱它們,以便根據瀏覽過程當中產生的事件序列做出決定。 例子以下:
import { Router, NavigationStart } from '@angular/router';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-routable',
templateUrl: './routable.component.html',
styleUrls: ['./routable.component.css']
})
export class Routable1Component implements OnInit {
navStart: Observable<NavigationStart>;
constructor(private router: Router) {
// Create a new Observable that publishes only the NavigationStart event
this.navStart = router.events.pipe(
filter(evt => evt instanceof NavigationStart)
) as Observable<NavigationStart>;
}
ngOnInit() {
this.navStart.subscribe(evt => console.log('Navigation Started!'));
}
}
複製代碼
ActivatedRoute 是一個可注入的路由器服務,它使用可觀察對象來獲取關於路由路徑和路由參數的信息。好比,ActivatedRoute.url
包含一個用於彙報路由路徑的可觀察對象。結合 Angular基礎知識學習(二)中動態路由的JS跳轉,此處咱們僅須要修改 product-detail.component.ts
文件:
import { Component, OnInit } from '@angular/core';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-product-detail',
templateUrl: './product-detail.component.html',
styleUrls: ['./product-detail.component.css']
})
export class ProductDetailComponent implements OnInit {
constructor(public router: ActivatedRoute) {
}
ngOnInit(): void {
this.router.url.subscribe(url => console.log('The URL changed to: ' + url));
}
}
複製代碼
頁面測試結果爲:
又好比 ActivatedRoute.queryParams
包含路由跳轉傳遞參數的可觀察對象。仍是結合我以前文章的案例,修改 news.component.ts
文件:
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.css']
})
export class NewsComponent implements OnInit {
nums: any[] = [];
constructor(public router: ActivatedRoute) {
this.router.queryParams.subscribe((data) => {
console.log(data);
});
}
ngOnInit(): void {
}
}
複製代碼
頁面測試結果爲:
響應式表單具備一些屬性,它們使用可觀察對象來監聽表單控件的值。 FormControl
的 valueChanges
屬性和 statusChanges
屬性包含了會發出變動事件的可觀察對象。訂閱可觀察的表單控件屬性是在組件類中觸發應用邏輯的途徑之一。好比:
import { FormGroup } from '@angular/forms';
@Component({
selector: 'my-component',
template: 'MyComponent Template'
})
export class MyComponent implements OnInit {
nameChangeLog: string[] = [];
heroForm: FormGroup;
ngOnInit() {
this.logNameChange();
}
logNameChange() {
const nameControl = this.heroForm.get('name');
nameControl.valueChanges.forEach(
(value: string) => this.nameChangeLog.push(value)
);
}
}
複製代碼