我在上上篇文章中介绍了父子组件间通过 Input 和 Output 的交流方式。现在我会介绍组件间交流的其他两种方法,viewChild 和 data service。我将这篇文章分为两部分。首先看 viewChild 部分吧。
通过 viewChild 传递数据
什么是 viewChild?
viewChild 就是准许一个组件被注入到别的组件中。并且指明了该可用子组件有了通往父组件的通道。简单说来,就是如果我们想要子组件的特性,我们就可以使用 viewChild 这个神器。为了讲得详细点,以下面的代码为例。先创建两个组件,一个为父组件,另一个为子组件。 下面是 child.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
counter :number = 0;
IncreaseNumber():void{
this.counter++;
}
constructor() { }
ngOnInit() {
}
}
从这个代码块中,我们可以知道,该组件有一个 counter 属性和一个 IncreaseNumber 方法。每次调用 IncreaseNumber 方法,counter的值就会自增一次。现在我们看看父组件。 parent.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import{ChildComponent} from './child.component'
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
@ViewChild(ChildComponent) private childcomponent : ChildComponent;
Increase():void{
this.childcomponent.IncreaseNumber();
}
Dicrease():void{
this.childcomponent.counter--;
}
constructor() { }
ngOnInit() {
}
}
现在一步步分析上面的代码块。
- import {ViewChild} from '@angular/core',再 import进子组件。
@ViewChild(ChildComponent) private childcomponent : ChildComponent;
这句代码非常重要,用于查询子组件,并在本地创建的子组件对象 childcomponent 中注入相同的属性。父组件同样有两个方法,自增和自减。父组件的模板可以改成这样子:
<p>
<b>@ViewChild with Components..</b>
<br>
<br>
<input type="button" (click)="Increase()">
<input type="button" (click)="Decrease()">
<app-child></app-child>
</p>
可以看到,我们在父组件模板中实例化了子组件。
通过 data service 传递数据
到目前为止,我们已经知道了如何在相关组件间传递数据,那么如果是不想关的组件呢?我们通常会用 service 来实现数据传递。共享数据背后的思想是共享服务,他将所有被组件中用到的数据同步在一起。就像下面这个例子: 首先来个data service:Data.service.ts
import { Injectable } from '@angular/core';
import {BehaviorSubject} from 'rxjs'
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject < string > ("Start");
constructor() {}
changemessage(message: string): void {
this.messageSource.next(message);
}
}
现在我们来分析一下上面这个代码块:
- import { Injectable } from '@angular/core' 引进 @Injectable 装饰器,这可以让其他组件和模块使用该服务类的功能。
- import {BehaviorSubject} from 'rxjs' 这可以返回一种Observable类型,从而订阅不同类型的消息。这个 service 里面定义了一种changemessage(),它会返回从 Observable 那里获取到的数据。为了让各组件可以使用到这个服务,我们需要在根模块中将这个 service 以 provider:[DataService]的形式引入。 引入该服务的组件 service.component.ts
import { Component, OnInit } from '@angular/core';
import{DataService} from '../data.service';
@Component({
selector: 'app-secondcomponent',
templateUrl: './secondcomponent.component.html',
styleUrls: ['./secondcomponent.component.css']
})
export class SecondcomponentComponent implements OnInit {
childmessage: string = "";
counter:number = 0;
constructor(private data: DataService) {}
ngOnInit() {
this.data.currentmessage.subscribe(Message => this.childMessage);
}
newmessage(): void {
this.data.changemessage("changing counter from sibling " + this.counter++);
}
}
总结:
- 通过 @Injectable 装饰器添加 service;
- 使用 RxJs 中的 BehaviorSubject,返回数据为 Observable 类型;
- 订阅一些可变属性,在组件中给它重新赋值。
参考:https://dzone.com/articles/angular-component-communication-day-2