简体   繁体   English

Angular4-让多个不相关的组件互相通知更新数据的问题,以及是否有一种更简洁的编码方法?

[英]Angular4 - let multiple unrelated components notify each other of the problem of updating data, and whether there is a cleaner coding method?

I have encountered a project in progress, let multiple unrelated components notify each other of the update data, is there a cleaner coding method? 我遇到了一个正在进行的项目,让多个不相关的组件将更新数据相互通知,是否有一种更简洁的编码方法?

There are 3 components (more likely later) and a common-data component. 有3个组件(以后可能会使用)和一个公共数据组件。 They have no parent-child relationship with each other and only show on the same screen. 他们彼此之间没有亲子关系,只显示在同一屏幕上。

The desired effect is to press the button of any component, update the contents of common-data, and notify yourself and other components to fetch new messages from common-data. 所需的效果是按下任何组件的按钮,更新公共数据的内容,并通知自己和其他组件从公共数据中获取新消息。

At present, my approach is to use Rx's Observable and Subscription, but they must be imported in the component.ts and service.ts files of each component, and a lot of duplicate code appears, it is very messy, I don't know what is better. 目前,我的方法是使用Rx的Observable和Subscription,但是必须将它们导入每个组件的component.ts和service.ts文件中,并且出现很多重复的代码,这很混乱,我不知道什么是更好的。 practice? 实践?

Thanks! 谢谢!

My code : The sample name is test-a-comp (abc and so on, the code is the same) 我的代码:样本名称为test-a-comp(abc等,代码相同)

test-a-comp.html 测试-A-comp.html

<p>
{{ownMessage}}
</p>
<button (click)="sendChange()">update</button>

test-a-comp.component 测试-A-comp.component

import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { CommonData } from '../common-data/common-data';
import { TestACompService } from './test-a-comp.service';
import { TestBCompService } from '../test-b-comp/test-b-comp.service';
import { TestCCompService } from '../test-c-comp/test-c-comp.service';

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

  subscription: Subscription;
  ownMessage;

  constructor(
    private testAService: TestACompService,
    private testBService: TestBCompService,
    private testCService: TestCCompService,
  ) {
    this.subscription = this.testAService.getMessage()
      .subscribe((test) => {
        CommonData.message = test;
      });
    this.subscription = this.testBService.getMessage()
      .subscribe(() => {
        this.ownMessage = CommonData.message;
      });
    this.subscription = this.testCService.getMessage()
      .subscribe(() => {
        this.ownMessage = CommonData.message;
      });
  }

  ngOnInit() {
  }

  sendChange() {
    this.testAService.sendMessage();
  }

}

test-a-comp.service: 测试-A-comp.service:

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

@Injectable()
export class TestACompService {
  subscription: Subscription;

  private subject = new Subject<any>();

  constructor() {
  }

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

  sendMessage(): void {
    this.subject.next('update message from A');
  }

}

As far as i understand & you've mentioned in the above, there is a button in one of the component (test-a-component.html). 据我了解,您在上面提到的一个组件(test-a-component.html)中有一个按钮。 If you update the button, you need to send message to other components which are subscribed. 如果更新按钮,则需要将消息发送到其他已订阅的组件。

The Components which have no Parent-Child relationship can communicate via a service: 没有父子关系的组件可以通过服务进行通信:

  1. Create a single service file (In your case: test-a-comp.service) 创建一个服务文件(在您的情况下:test-a-comp.service)
  2. Create a Subject on what data you need to communicate via this service: 创建您需要通过此服务传达哪些数据的主题:

      export class testMessageService { constructor() {} // Observable string sources private message = new Subject<string>(); //Observable string streams testMessage$ = this.message.asObservable(); constructor() {} // Method to send message when a button is clicked sendMessage(message: string) { this.message.next(message); } /* You don't need "getMessage()" method as you've already subscribed to the observables. There subscribed Observable string streams are injected in your components (As below point 3) to display / do other operation on the message. */ } 
  3. In your other Components, where you want to receive messages, do the following: 在要接收消息的其他组件中,执行以下操作:

      export class TestComponent 1 { myMessage1: string; constructor(private TestMessageService: testMessageService) {} TestMessageService.testMessage$.subscribe(message => { this.myMessage1 = message; }); } export class TestComponent 2 { myMessage2: string; constructor(private TestMessageService: testMessageService) {} TestMessageService.testMessage$.subscribe(message => { this.myMessage2 = message; }); } export class TestComponent 3 { myMessage3: string; constructor(private TestMessageService: testMessageService) {} TestMessageService.testMessage$.subscribe(message => { this.myMessage3 = message; }); } 

    For more information/guidance refer Component interaction via a common service: https://angular.io/guide/component-interaction 有关更多信息/指导,请参见通过公共服务进行组件交互: https : //angular.io/guide/component-interaction

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM