如何在2个不同模块的2个不同组件之间共享数据。
我有2个模块仪表板和首选项,以及两个组件dashboard.component.ts和preference.component.ts
我已经创建了bar.service.ts服务来传递数据,并且我的服务包含以下代码
private messageSource = 'orderView';
changeMessage(message: string) {
this.messageSource = message;
}
preference.component.ts包含以下代码
this.bar.changeMessage('groupByView');
dashboard.component.ts包含以下代码
console.log(this.bar.messageSource);
我正在使用路由和首选项显示首选项页面和仪表板显示仪表板页面。
当用户位于首选项页面上并将messageSource更改为groupByView时,它不会反映在仪表板页面上。
仪表板页面始终在messageSource中包含orderView值
答案 0 :(得分:1)
您可以使用可观察对象(它们与Angular高度集成)。
服务(YourService):
@Injectable() // { providedIn: 'root' } ? read below
export class YourService {
messageSourceSubject: BehaviorSubject<string> = new BehaviorSubject<string>('orderView');
messageSource: Observable<string> = this.messageSourceSubject.asObservable();
publishMessage(message: string): void {
this.messageSourceSubject.next(message);
}
}
您的服务必须在根服务(Injectable的providedIn
属性中注册),否则您必须将该服务放入某些提供程序(可能是您的根模块)中。
您的组件:
当您需要使用TypeScript(在组件TS代码中)获取数据时,您需要:
constructor(public yourService: YourService) {
this.yourService
.messageSource
.subscribe(message => console.log(message));
// don't forget to unsubscribe on destroy (`subscription.unsubscribe` - subscribe returns it) or `pipe(takeUntil(this.destroy))` - takeUntil is an RxJS operator from `rxjs/operators`.
}
如果您需要HTML:
<div>{{ yourService.messageSource | async }}</div>
async
关键字是AsyncPipe(来自@angular/common
的CommonModule)。如果您使用AsyncPipe,则无需在任何地方退订,它会自行处理。
此外,如果您在组件中使用订阅,则一定不要忘记取消订阅(我在上面的代码中给出了一些评论)
别忘了将所有内容导入组件。
此外,如果您在组件中使用ChangeDetectionStrategy.OnPush
,则必须告诉Angular在将来某个组件上运行更改检测。可以使用ChangeDetectorRef
依赖性(可以通过DI来获得)及其方法markForCheck
来完成。
答案 1 :(得分:1)
您可以使用Subject
酒吧服务:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class BarService {
// Observable string sources
private messageSource = new Subject<string>();
messageSource$ = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message);
}
}
首选项:
import { Component, OnInit } from '@angular/core';
import { BarService } from '../bar.service';
@Component({
selector: 'app-preference',
templateUrl: './preference.component.html',
styleUrls: ['./preference.component.css']
})
export class PreferenceComponent implements OnInit {
constructor(private barService: BarService) { }
ngOnInit() {
}
onChange() {
this.barService.changeMessage(`Update dashboard at ${ new Date()}`)
}
}
首选项模板:
<p>
preference works!
<button (click)="onChange()">Update Dashboard</button>
</p>
仪表板组件:
import { Component, OnInit } from '@angular/core';
import { BarService } from '../bar.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
changeMessage: any;
constructor(private barService: BarService) { }
ngOnInit() {
this.barService.messageSource$.subscribe((res)=>{
this.changeMessage = res;
});
}
}
信息中心模板:
<p>
dashboard works! {{changeMessage}}
</p>