如何在彼此不直接链接的角度组件之间共享数据?

Posted

技术标签:

【中文标题】如何在彼此不直接链接的角度组件之间共享数据?【英文标题】:How to share data between angular components which are not directly linked with each other? 【发布时间】:2020-04-10 20:09:29 【问题描述】:

我正在构建一个 Angular 应用程序。我通过点击事件从第一个组件导航到第二个组件。在导航到第二个组件时,我希望将一些数据从第一个组件传递到第二个组件。我已经按照教程来实现这一点,但无法做到。下面是我的代码

第一个组件.ts

export class FirstComponent implements OnInit 

@Output() messageEvent = new EventEmitter<string>();

constructor()


ngOnInit() 


sendMessagetoSecond(ahu) 
    this.messageEvent.emit(ahu)
    console.log(ahu)
  

第一个组件.html

<map name="ahuMap">
   <area shape="rect" coords="818,232,917,262" (click)="sendMessagetoSecond()" [routerLink]="['/secondComponent']">
 </map>

第二个组件.ts

ahu : string

receiveMessage($event) 
  this.ahu = $event

第二个组件.html

<body>
  <app-first (messageEvent)="receiveMessage($event)"></app-first>
  ahu: ahu
  <div>
   ....
  </div>
</body>

这是我尝试过的。我面临的问题是: 1-变量未转移到第二个组件 第一个组件的 2-HTML 也正在第二个组件中加载。 我有什么遗漏或做错了吗?

【问题讨论】:

receiveMessage函数中,如果你console.log($event),你会看到什么? 为什么你的区域组件上有一个 [routerLink]="['/secondComponent']" ? 从 sendMessageToSecond 方法中删除 routerLink 和路由(在发出之后)-> this.router.navigate(['/secondComponent']); 用于在兄弟或不相关组件之间传输数据使用服务和可观察对象。 如果字符串长度不大可以直接通过路由传递,如果不想让别人看到字符串,加密后传入路由 【参考方案1】:

您可以使用共享服务在组件之间传递数据。当你有随时间变化的数据时,RxJS BehaviorSubject 在这种情况下将非常有用。它将确保组件始终接收最新的数据。

为此,

您首先需要创建一个服务,您将在其中添加一个私有 BehaviorSubject,该 BehaviorSubject 将保存您希望在组件之间共享的消息的当前值。还有两种方法,一种将当前数据流处理为可被组件使用的可观察对象,另一种用于更新消息的值。

data.service.ts

import  Injectable  from '@angular/core';
import  BehaviorSubject, Observable  from 'rxjs';

@Injectable()
export class DataService 

  private messageSource = new BehaviorSubject('default message');

  constructor() 

  fetchMessage(): Observable<string> 
    return this.messageSource.asObservable();
  

  sendMessage(message: string) 
    this.messageSource.next(message)
  


创建服务后,您只需将其注入组件的构造函数中,然后调用其方法 fetchMessage/sendMessage 即可获取或更改您的消息值。

因此,您可以使用它来将数据从父级传递给子级,例如:

parent.component.ts

import  Component, OnInit  from '@angular/core';
import  DataService  from "./data.service";

@Component(
  selector: 'parent',
  template: `
    message
    <button (click)="newMessage()">send Message</button>
  `
)
export class ParentComponent implements OnInit 

  message:string;

  constructor(private data: DataService)  

  ngOnInit() 
    this.data.fetchMessage.subscribe(message => this.message = message)
  

  newMessage() 
    this.data.sendMessage("Hello from Parent Component")
  


child.component.ts

import  Component, OnInit  from '@angular/core';
import  DataService  from "./data.service";

@Component(
  selector: 'child',
  template: `
    message
  `
)
export class ChildComponent implements OnInit 

  message:string;

  constructor(private data: DataService)  

  ngOnInit() 
    this.data.fetchMessage().subscribe(message => this.message = message)
  


希望对你有所帮助。

【讨论】:

【参考方案2】:

in this demo, I am passing a value from app.component.ts to view component.component.ts using test.service

在这里,在 app.component.ts 的构造函数中为 test.service 中的变量赋值,然后将该值赋给视图 component.component.ts 中的变量。

【讨论】:

【参考方案3】:

做到这一点的方法是使用 observables。您可以根据需要使用主题或行为主题。然后你可以从另一个组件订阅并采取相应的行动。所以实现如下:

@Injectable( providedIn: 'root' )

导出类 MessageService 私人主题 = 新主题();

sendMessage(message: string) 
    this.subject.next( text: message );


clearMessages() 
    this.subject.next();


getMessage(): Observable<any> 
    return this.subject.asObservable();


所以在另一个组件中你可以像下面这样订阅:

constructor(private messageService: MessageService) 
    // subscribe to home component messages
    this.subscription = this.messageService.getMessage().subscribe(message => 
      if (message) 
        this.messages.push(message);
       else 
        // clear messages when empty message received
        this.messages = [];
      
    );

对于发射部分,我们可以在下面做:

export class HomeComponent 
constructor(private messageService: MessageService)  

sendMessage(): void 
    // send message to subscribers via observable subject
    this.messageService.sendMessage('Message from Home Component to App Component!');


clearMessages(): void 
    // clear messages
    this.messageService.clearMessages();


这些只是挑选的示例代码,您可以根据需要添加多个订阅。

【讨论】:

以上是关于如何在彼此不直接链接的角度组件之间共享数据?的主要内容,如果未能解决你的问题,请参考以下文章

云计算openstack共享组件-消息队列rabbitmq

云计算OpenStack共享组件---信息队列rabbitmq

允许在角度组件之间共享 relative 和 flex

Vuex概述

react js中不相关的组件之间如何共享数据?

在 React 中的组件之间共享数据