簡體   English   中英

有沒有一種方法可以在不使用angualr中使用事件發射器的情況下在不是父級和子級的兩個組件之間進行通信?

[英]Is there a method to do communication between two components which are not parent and child without using event emitter in angualr?

在angular中,我們可以使用@input和@output在父級和子級兩個組件之間進行通信,但是有沒有一種方法可以在不使用事件發射器的情況下在父級和子級兩個組件之間進行通信?

您還可以使用Rxjs中主題對此進行存檔

1. /創建服務

 import { Injectable } from '@angular/core';
 import { Subject } from 'rxjs/Subject';
 @Injectable()
 export class MessageService {
  public message = new Subject<string>();
  setMessage(value: string) {
    this.message.next(value); //it is publishing this value to all the subscribers 
    that have already subscribed to this message
  }
}

2. /現在,將此服務注入component1.ts中,並將其實例傳遞給構造函數。 也對component2.ts執行此操作。 使用此服務實例將#message的值傳遞給服務函數setMessage

 import { Component } from '@angular/core';
 import { MessageService } from '../../service/message.service';
 @Component({
   selector: 'app-home',
   templateUrl: './home.component.html',
   styleUrls: ['./home.component.css']
 })
export class Component1Component {
constructor(public messageService:MessageService) { }
 setMessage(event) {
   console.log(event.value);
   this.messageService.setMessage(event.value);
 }
}

3. /在component2.ts內部,訂閱和取消訂閱(以防止內存泄漏)

import { Component, OnDestroy } from '@angular/core';
import { MessageService } from './service/message.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class Component2Component {
 message: string;
 subscription: Subscription;
constructor(public messageService: MessageService) { }
ngOnInit() {
this.subscription = this.messageService.message.subscribe(
  (message) => {
    this.message = message;
  }
 );
}
ngOnDestroy() {
  this.subscription.unsubscribe();
 }
}

使用Observables的解決方案。

//message.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class MessageService {

  private messageCommand = new Subject<string>();
  messageCommand$ = this.messageCommand.asObservable();

  invokeMessage(msg: string) {
    this.messageCommand.next(msg);
  }
}

//component-one.ts

import { Component, OnInit } from '@angular/core';
import { MessageService } from '../services/message.service';

@Component({
  selector: 'app-component-one',
  templateUrl: './component-one.component.html',
  styleUrls: ['./component-one.component.css']
})
export class ComponentOneComponent implements OnInit {

  constructor(private messageService: MessageService) { }

  ngOnInit() {
  }

  yourActionMethod() {
    this.messageService.invokeMessage('This is from component one');
  }
}

//component-two.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { MessageService } from '../services/message.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-component-two',
  templateUrl: './component-two.component.html',
  styleUrls: ['./component-two.component.css']
})
export class ComponentTwoComponent implements OnInit, OnDestroy {

  messageSubscription: Subscription;
  message: string;

  constructor(private messageService: MessageService) { }

  ngOnInit() {
    this.subscribeToMessageEvents();
  }

  ngOnDestroy(): void {
    this.messageSubscription.unsubscribe();
  }

  subscribeToMessageEvents() {
    this.messageSubscription = this.messageService.messageCommand$.subscribe(
      (msg: string) => {
        this.message = msg;
      }
    );
  }

}

在這里,我使用了一個包含可觀察類型的字符串的服務類。

然后從組件一開始,使用我們的消息服務中的invokeMessage方法發布一條消息。

需要接收消息的組件,在我們的例子中是第二個組件,應該在消息服務中訂閱messsageCommand $。

您必須記住的一件事是,無論何時訂購可觀察對象,請確保在組件被銷毀時取消訂閱。

1)是的,如文檔中所述,實際上您可以利用服務進行組件交互。 他們不必是親戚(親子)。 查看上面的鏈接以獲取示例實現。

2)使用服務執行此操作的另一種方法是以下方法,但是它將使用EventEmitter:

@Injectable()
export class CommunicationService { 
  isTrigger: boolean = false;
  @Output() change: EventEmitter<boolean> = new EventEmitter();

  toggle() {
    this.isTrigger = !this.isTrigger;
    this.change.emit(this.isTrigger);
  }

}

在“父級”部分,

// somewhere in this component will call the emit() method
.
.
emit() {
  this.communicationService.toggle();
}

在目標組件上,

isTrigger: boolean = false
.
.
this.communicationService.change.subscribe(isTrigger => {
  this.isTrigger = isTrigger;
});

3)國家管理。 根據項目的復雜性,最好使用狀態管理框架(例如NgRx) ,因為您的主要組件會更整潔。 如果您使用過React / Redux,這對您將非常熟悉。 如果您的應用程序確實有要求,我只會推薦它。 否則,將Observables / RxJS和EventEmitters結合使用將綽綽有余。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM