首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Angular 中的可观察对象

Angular 使用可观察对象作为处理各种常用异步操作的接口。比如:

  • EventEmitter 类派生自 Observable
  • HTTP 模块使用可观察对象来处理 AJAX 请求和响应。
  • 路由器和表单模块使用可观察对象来监听对用户输入事件的响应。

事件发送器 EventEmitter

Angular 提供了一个 EventEmitter 类,它用来从组件的 @Output() 属性中发布一些值。EventEmitter 扩展了 Observable,并添加了一个 emit() 方法,这样它就可以发送任意值了。当你调用 emit() 时,就会把所发送的值传给订阅上来的观察者的 next() 方法。

这种用法的例子参见 EventEmitter 文档。下面这个范例组件监听了 openclose 事件:

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

组件的定义如下:

EventEmitter

代码语言:javascript
复制
content_copy@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 方法调用中返回了可观察对象。例如,http.get(‘/api’) 就会返回可观察对象。相对于基于承诺(Promise)的 HTTP API,它有一系列优点:

  • 可观察对象不会修改服务器的响应(和在承诺上串联起来的 .then() 调用一样)。反之,你可以使用一系列操作符来按需转换这些值。
  • HTTP 请求是可以通过 unsubscribe() 方法来取消的。
  • 请求可以进行配置,以获取进度事件的变化。
  • 失败的请求很容易重试。

Async 管道

AsyncPipe 会订阅一个可观察对象或承诺,并返回其发出的最后一个值。当发出新值时,该管道就会把这个组件标记为需要进行变更检查的(译注:因此可能导致刷新界面)。

下面的例子把 time 这个可观察对象绑定到了组件的视图中。这个可观察对象会不断使用当前时间更新组件的视图。

Using async pipe

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

路由器 (router)

Router.events 以可观察对象的形式提供了其事件。 你可以使用 RxJS 中的 filter() 操作符来找到感兴趣的事件,并且订阅它们,以便根据浏览过程中产生的事件序列作出决定。 例子如下:

Router events

代码语言:javascript
复制
content_copyimport { 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 the 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 是一个可注入的路由器服务,它使用可观察对象来获取关于路由路径和路由参数的信息。比如,ActivateRoute.url 包含一个用于汇报路由路径的可观察对象。例子如下:

ActivatedRoute

代码语言:javascript
复制
content_copyimport { 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)

响应式表单具有一些属性,它们使用可观察对象来监听表单控件的值。FormControlvalueChanges 属性和 statusChanges 属性包含了会发出变更事件的可观察对象。订阅可观察的表单控件属性是在组件类中触发应用逻辑的途径之一。比如:

Reactive forms

代码语言:javascript
复制
content_copyimport { 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)    );  }}

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com