Angular9 可觀察對象

2020-07-02 14:44 更新

Angular 中的可觀察對象

Angular 使用可觀察對象作為處理各種常用異步操作的接口。比如:

  • EventEmitter 類派生自 Observable。

  • HTTP 模塊使用可觀察對象來處理 AJAX 請求和響應。

  • 路由器和表單模塊使用可觀察對象來監(jiān)聽對用戶輸入事件的響應。

在組件之間傳遞數(shù)據(jù)

Angular 提供了一個 EventEmitter 類,它用來通過組件的 @Output() 裝飾器 發(fā)送一些值。EventEmitter 擴展了 RxJS Subject,并添加了一個 emit() 方法,這樣它就可以發(fā)送任意值了。當你調(diào)用 emit() 時,就會把所發(fā)送的值傳給訂閱上來的觀察者的 next() 方法。

這種用法的例子參見 EventEmitter 文檔。下面這個范例組件監(jiān)聽了 openclose 事件:

<zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>

組件的定義如下:

//EventEmitter


@Component({
  selector: 'zippy',
  template: `
  <div class="zippy">
    <div (click)="toggle()">Toggle</div>
    <div [hidden]="!visible">
      <ng-content></ng-content>
    </div>
  </div>`})


export class ZippyComponent {
  visible = true;
  @Output() open = new EventEmitter<any>();
  @Output() close = new EventEmitter<any>();


  toggle() {
    this.visible = !this.visible;
    if (this.visible) {
      this.open.emit(null);
    } else {
      this.close.emit(null);
    }
  }
}

HTTP

Angular 的 HttpClient 從 HTTP 方法調(diào)用中返回了可觀察對象。例如,"http.get(‘/api’)" 就會返回可觀察對象。相對于基于承諾(Promise)的 HTTP API,它有一系列優(yōu)點:

  • 可觀察對象不會修改服務器的響應(和在承諾上串聯(lián)起來的 .then() 調(diào)用一樣)。反之,你可以使用一系列操作符來按需轉(zhuǎn)換這些值。

  • HTTP 請求是可以通過 unsubscribe() 方法來取消的。

  • 請求可以進行配置,以獲取進度事件的變化。

  • 失敗的請求很容易重試。

Async 管道

AsyncPipe 會訂閱一個可觀察對象或承諾,并返回其發(fā)出的最后一個值。當發(fā)出新值時,該管道就會把這個組件標記為需要進行變更檢查的(譯注:因此可能導致刷新界面)。

下面的例子把 time 這個可觀察對象綁定到了組件的視圖中。這個可觀察對象會不斷使用當前時間更新組件的視圖。

//Using async pipe


@Component({
  selector: 'async-observable-pipe',
  template: `<div><code>observable|async</code>:
       Time: {{ time | async }}</div>`
})
export class AsyncObservablePipeComponent {
  time = new Observable<string>(observer => {
    setInterval(() => observer.next(new Date().toString()), 1000);
  });
}

路由器 (router)

Router.events 以可觀察對象的形式提供了其事件。 你可以使用 RxJS 中的 filter() 操作符來找到感興趣的事件,并且訂閱它們,以便根據(jù)瀏覽過程中產(chǎn)生的事件序列作出決定。 例子如下:

//Router events


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 是一個可注入的路由器服務,它使用可觀察對象來獲取關于路由路徑和路由參數(shù)的信息。比如,ActivatedRoute.url 包含一個用于匯報路由路徑的可觀察對象。例子如下:

//ActivatedRoute


import { ActivatedRoute } from '@angular/router';


@Component({
  selector: 'app-routable',
  templateUrl: './routable.component.html',
  styleUrls: ['./routable.component.css']
})
export class Routable2Component implements OnInit {
  constructor(private activatedRoute: ActivatedRoute) {}


  ngOnInit() {
    this.activatedRoute.url
      .subscribe(url => console.log('The URL changed to: ' + url));
  }
}

響應式表單 (reactive forms)

響應式表單具有一些屬性,它們使用可觀察對象來監(jiān)聽表單控件的值。 FormControlvalueChanges 屬性和 statusChanges 屬性包含了會發(fā)出變更事件的可觀察對象。訂閱可觀察的表單控件屬性是在組件類中觸發(fā)應用邏輯的途徑之一。比如:

//Reactive forms


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)
    );
  }
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號