Angular 6 中组件之间的数据共享
Data sharing between components in Angular 6
我创建了 2 个组件和一个服务,如下所示,
分量-interaction.service.ts
@Injectable()
export class ComponentInteractionService {
public dataSubject = new BehaviorSubject<string>("Test");
getTestData(): Observable<any> {
return this.dataSubject.asObservable();
}
pustTestData(dataToPush: string): void {
this.dataSubject.next(dataToPush);
}
}
first.component.ts
export class FirstComponent {
constructor(private componentInteractionService: ComponentInteractionService) {
componentInteractionService.getTestData().subscribe(data=> {
console.log("Received at 1 -- " + data);
});
}
sendTestData(): void {
this.componentInteractionService.pustTestData("sending data from 1");
}
}
second.component.ts
export class SecondComponent {
constructor(private componentInteractionService: ComponentInteractionService) {
componentInteractionService.getTestData().subscribe(data=> {
console.log("Received at 2 -- " + data);
});
}
}
我目前面临的问题是
在页面加载时,两个组件订阅者都被触发,但是当我使用 sendTestData() 方法在 FirstComponent 中推送数据时,仅FirstComponent 中的订阅者被触发。 SecondComponent 中的订阅者未被触发。
我应该怎么做才能让两个订阅者都触发使用 sendTestData() 方法推送数据?
我的控制台日志如下..
在 1 收到 -- 测试
2 点收到 -- 测试
在 1 接收 -- 从 1 发送数据
预期输出..
在 1 收到 -- 测试
2 点收到 -- 测试
在 1 接收 -- 从 1 发送数据
在 2 接收 -- 从 1 发送数据
对我来说工作得很好。检查这个 demo 控制台
这里是相关代码
common.service.ts
@Injectable()
export class CommonService {
public dataSubject$: Subject<string> = new BehaviorSubject<string>("Test");
getData(): Observable<any> {
return this.dataSubject$.asObservable();
}
setData(dataToPush: string): void{
this.dataSubject$.next(dataToPush);
}
}
first.component.ts
@Component({
selector: 'app-first',
template: `First Component data`,
})
export class FirstComponent implements OnInit {
constructor(
private commonService: CommonService,
) {
}
ngOnInit(){
this.sendCommonData();
this.getCommonData();
}
getCommonData () {
this.commonService.getData().subscribe(data=> {
console.log("Received at 1 -- " + data);
})
}
sendCommonData() {
this.commonService.setData("sending data from first");
}
}
second.component.ts
import { Component, OnInit } from '@angular/core';
import { CommonService } from './common.service';
@Component({
selector: 'app-second',
template: `Second Component data `,
})
export class SecondComponent implements OnInit {
constructor(
private commonService: CommonService,
) {
}
ngOnInit(){
this.getCommonData();
}
getCommonData () {
this.commonService.getData().subscribe(data=> {
console.log("Received at 2 -- " + data);
})
}
}
sendTestData(): void {
this.componentInteractionService.pustTestData("sending data from 1");
// must call the observable once after adding new data
this.commonService.getData();
}
您必须在为行为主体设置新数据后调用可观察对象。
这是因为您在 AppComponentOne
和 AppComponentTwo
中都提供了两次相同的服务,所以它们都有相同服务的不同实例。
清空 providers
组件数组并在 app.module.ts
内提供服务
@Component({
selector: 'app-distinct-first-component',
template: '<button (click)="sendTestData()">Click to send Data</button>',
providers: [ComponentService] // <= remove this line from both components
})
app.module.ts
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, HelloComponent,
FirstComponent, SecondComponent
],
bootstrap: [ AppComponent ],
providers: [ComponentService] // <= provide it here
})
export class AppModule { }
我创建了 2 个组件和一个服务,如下所示,
分量-interaction.service.ts
@Injectable()
export class ComponentInteractionService {
public dataSubject = new BehaviorSubject<string>("Test");
getTestData(): Observable<any> {
return this.dataSubject.asObservable();
}
pustTestData(dataToPush: string): void {
this.dataSubject.next(dataToPush);
}
}
first.component.ts
export class FirstComponent {
constructor(private componentInteractionService: ComponentInteractionService) {
componentInteractionService.getTestData().subscribe(data=> {
console.log("Received at 1 -- " + data);
});
}
sendTestData(): void {
this.componentInteractionService.pustTestData("sending data from 1");
}
}
second.component.ts
export class SecondComponent {
constructor(private componentInteractionService: ComponentInteractionService) {
componentInteractionService.getTestData().subscribe(data=> {
console.log("Received at 2 -- " + data);
});
}
}
我目前面临的问题是
在页面加载时,两个组件订阅者都被触发,但是当我使用 sendTestData() 方法在 FirstComponent 中推送数据时,仅FirstComponent 中的订阅者被触发。 SecondComponent 中的订阅者未被触发。 我应该怎么做才能让两个订阅者都触发使用 sendTestData() 方法推送数据?
我的控制台日志如下..
在 1 收到 -- 测试
2 点收到 -- 测试
在 1 接收 -- 从 1 发送数据
预期输出..
在 1 收到 -- 测试
2 点收到 -- 测试
在 1 接收 -- 从 1 发送数据
在 2 接收 -- 从 1 发送数据
对我来说工作得很好。检查这个 demo 控制台
这里是相关代码
common.service.ts
@Injectable()
export class CommonService {
public dataSubject$: Subject<string> = new BehaviorSubject<string>("Test");
getData(): Observable<any> {
return this.dataSubject$.asObservable();
}
setData(dataToPush: string): void{
this.dataSubject$.next(dataToPush);
}
}
first.component.ts
@Component({
selector: 'app-first',
template: `First Component data`,
})
export class FirstComponent implements OnInit {
constructor(
private commonService: CommonService,
) {
}
ngOnInit(){
this.sendCommonData();
this.getCommonData();
}
getCommonData () {
this.commonService.getData().subscribe(data=> {
console.log("Received at 1 -- " + data);
})
}
sendCommonData() {
this.commonService.setData("sending data from first");
}
}
second.component.ts
import { Component, OnInit } from '@angular/core';
import { CommonService } from './common.service';
@Component({
selector: 'app-second',
template: `Second Component data `,
})
export class SecondComponent implements OnInit {
constructor(
private commonService: CommonService,
) {
}
ngOnInit(){
this.getCommonData();
}
getCommonData () {
this.commonService.getData().subscribe(data=> {
console.log("Received at 2 -- " + data);
})
}
}
sendTestData(): void {
this.componentInteractionService.pustTestData("sending data from 1");
// must call the observable once after adding new data
this.commonService.getData();
}
您必须在为行为主体设置新数据后调用可观察对象。
这是因为您在 AppComponentOne
和 AppComponentTwo
中都提供了两次相同的服务,所以它们都有相同服务的不同实例。
清空 providers
组件数组并在 app.module.ts
@Component({
selector: 'app-distinct-first-component',
template: '<button (click)="sendTestData()">Click to send Data</button>',
providers: [ComponentService] // <= remove this line from both components
})
app.module.ts
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, HelloComponent,
FirstComponent, SecondComponent
],
bootstrap: [ AppComponent ],
providers: [ComponentService] // <= provide it here
})
export class AppModule { }