How to set or pass a property state between unnest

2020-02-16 04:58发布

问题:

I develop a web application with tech Angular. But now I am having a problem, how can I pass or set a property from a compoennt to the other component, which are not parent-child component.

Detials: I have created a compoent called Serach, There is a button in this component, if this button is clicked, will call some REST APIs and will wait to get some data from backend. By calling this REST CALL, will in the other compoennt called Home show 'LOADING....'.

the component Search and the component HOME ist not parent-child component. and the Search compoent is in the Header Component, and Home Component will be shown, if the web app loaded. That means, that these 2 Components are be shown in the same time.

I have tried to use Message Service to transport a Message e.g. 'LOADING'.

<mat-sidenav-content>
    <div class="app-header">
      <app-header></app-header>
    </div>
    <div class="mat-sidenav-content">
      <main class="content">
        <app-breadcrumb></app-breadcrumb>
        <router-outlet></router-outlet>
      </main>
    </div>
  </mat-sidenav-content>

Search component is located in app header component.

the function in serach component is as follows:

public search(): void {
    this.messageService.sendMessage("LOADING");
    this.loadData.loadData(this.key).subscribe(() => {
      this.router.navigate(['overview']);
    }
      , (error) => {
        this.openDialog();
      }
    ); 
  }

the code in home.ts

export class HomeComponent implements OnInit {
  public message = [];
  subscription: Subscription;
  constructor(private messageService: MessageService,
    private router: Router) {
     this.subscription = this.messageService.getMessage().subscribe((message) => {
      this.message.push(message);
    });
  }
  ngOnInit() {
  }
}

and the HTML code:

<div *ngIf="message.includes('LOADING')">
  <app-loading></app-loading>
</div>

someone has any idea??

回答1:

To share data between two components that don't have a parent child relationship you would use a service like you explained. It hard to tell what the issue is without seeing your MessageService implementation.

I did throw together a simple example that you can review and apply to your situation. Linked below are a few resources to help explain Angular component interaction and a stackblitz with an example where I created a LoadingService similar to how you could create a MessageService, something similar to this...

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

@Injectable()
export class LoadingService {

  private isLoadingSource: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
  public isLoading: Observable<boolean> = this.isLoadingSource.asObservable();

  constructor() { }

  set loading(value: boolean) {
    this.isLoadingSource.next(value);
  }

}

Resources

https://stackblitz.com/edit/angular-gjpsgi

https://angular.io/guide/component-interaction

https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/