angular 定义对象_Angular 中的可观察对象

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

HTTP 模块使用可观察对象来处理 AJAX 请求和响应。

路由器和表单模块使用可观察对象来监听对用户输入事件的响应。

EventEmitter

Angular 提供了一个 EventEmitter 类,它用来通过组件的 @Output() 装饰器 发送一些值。EventEmitter 扩展了 RxJS Subject,并添加了一个 emit() 方法,这样它就可以发送任意值了。当你调用 emit() 时,就会把所发送的值传给订阅上来的观察者的 next() 方法。 我们来查看一下该类的定义:

export declare class EventEmitter extends Subject {

/**

* 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 一起在组件中使用以同步或异步方式发送自定义事件,并通过订阅实例来注册这些事件的处理程序。

接下来我们演示一个案例,在组件之间传递数据。

子组件 zippy.component.ts

import { Component, OnInit, Output, EventEmitter } from '@angular/core';

@Component({

selector: 'app-zippy',

templateUrl: '

点击该文本

'

})

export class ZippyComponent implements OnInit {

visible = true;

// tslint:disable-next-line: no-output-native

@Output() open = new EventEmitter();

// tslint:disable-next-line: no-output-native

@Output() close = new EventEmitter();

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

import { Component, OnInit } from '@angular/core';

@Component({

selector: 'app-home4',

templateUrl: '

我是home组件的内容

'

})

export class Home4Component implements OnInit {

constructor() { }

ngOnInit(): void {

}

onOpen(e) {

console.log(e);

}

onClose(e) {

console.log(e);

}

}

运行项目,在页面上点击文本内容,注意观察控制台输出的内容。如下图所示:

HTTP

Angular 的 HttpClient 从 HTTP 方法调用中返回了可观察对象。例如,http.get(‘/api’) 就会返回可观察对象。相对于基于承诺(Promise)的 HTTP API,它有一系列优点:可观察对象不会修改服务器的响应(和在承诺上串联起来的 .then() 调用一样)。反之,你可以使用一系列操作符来按需转换这些值。

HTTP 请求是可以通过 unsubscribe() 方法来取消的。

请求可以进行配置,以获取进度事件的变化。

失败的请求很容易重试。

关于讲解数据交互那一部分内容时,对于 get、post 请求都有测试案例,现在回头看当时比较疑惑的内容,现在就豁然开朗了。

Async 管道

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

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

import { Component, OnInit } from '@angular/core';

import { Observable } from 'rxjs';

@Component({

selector: 'app-asyncpipe',

templateUrl: '

observable|async:

Time: {{ time | async }}

'

})

export class AsyncpipeComponent implements OnInit {

time: Observable;

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: '

{{tim.date}}---{{tim.time}}

'

})

export class AsyncpipeComponent implements OnInit {

time2: Observable;

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)

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;

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;

}

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 {

}

}

页面测试结果为:

响应式表单 (reactive forms)

响应式表单具有一些属性,它们使用可观察对象来监听表单控件的值。 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)

);

}

}

参考文献

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值