如何在不同模块的angular中的两个不同组件之间共享数据

时间:2019-11-21 19:46:59

标签: angular typescript

如何在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值

2 个答案:

答案 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

Working Demo

酒吧服务:

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>