Angular 5 - 通过<router-outlet>无法正常工作的组件通信

时间:2018-02-01 16:17:19

标签: angular rxjs angular5

这让我发疯,有人可以告诉我为什么我不能通过组件进行交流吗?我试图从HomeComponent向RecipesComponent发送消息,反之亦然。当我点击testInstruction按钮时,它只会登录同一个组件。

import { Component, OnInit } from '@angular/core';

import { VoiceInstructionService } from './voice-instruction.service';
import { Subscription } from 'rxjs/Subscription';

@Component({
  selector: 'my-app',
  template: `<router-outlet></router-outlet>`
})
export class AppComponent {
    constructor() {}
}


@Component({
  selector: 'app-home',
  template: `<div><button type="button" (click)="testInstruction()">Test Instruction</button></div>`
})
export class HomeComponent {
  instructionSubscription: Subscription;

    constructor(private voiceInstructionService: VoiceInstructionService) {}

    ngOnInit() {
      this.instructionSubscription = this.voiceInstructionService.instruction$.subscribe(instruction => {
        console.log(instruction);
    }

    testInstruction(): void {
      this.voiceInstructionService.setInstruction('test');
    }
}

@Component({
  selector: 'app-recipes',
  template: `<div><button type="button" (click)="testInstruction()">Test Instruction</button></div>`
})
export class RecipesComponent {
  instructionSubscription: Subscription;

    constructor(private voiceInstructionService: VoiceInstructionService) {}

    ngOnInit() {
      this.instructionSubscription = this.voiceInstructionService.instruction$.subscribe(instruction => {
        console.log(instruction);
    }

    testInstruction(): void {
      this.voiceInstructionService.setInstruction('test');
    }
}

语音instruction.service

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

@Injectable()
export class VoiceInstructionService {

  subject = new Subject<string>();
  instruction$ = this.subject.asObservable();

  setInstruction(instruction: string) {
    this.subject.next(instruction);
  }
}

app.module:

import { routing } from './app.routing';
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule }    from '@angular/http';

import { AppComponent, HomeComponent, RecipesComponent }   from './app.component';
import { VoiceInstructionService } from './voice-instruction.service';

@NgModule({
  imports:      [ BrowserModule, HttpModule, routing ],
  declarations: [ AppComponent, HomeComponent, RecipesComponent ],
  providers: [ VoiceInstructionService ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }

app.routing:

import { ModuleWithProviders } from '@angular/core';
import { HomeComponent } from './app.component';
import { Routes, RouterModule } from '@angular/router';
import { RecipesComponent } from './app.component';

export const routes: Routes = [
  {
   path: '', redirectTo: 'home', pathMatch: 'full'
 },
 {
    path: 'home',
    component: HomeComponent
  },
  {
     path: 'recipes',
     component: RecipesComponent
  }
]

export const routing: ModuleWithProviders = RouterModule.forRoot(routes);

我也尝试在AppComponent上提供服务,但它不起作用。

  • Angular CLI:1.5.0
  • 节点:7.9.0
  • OS:darwin x64
  • Angular:5.2.3

- 更新

如果我将app.component修改为:

@Component({
  selector: 'my-app',
  template: `<router-outlet></router-outlet>`
})
export class AppComponent implements OnInit {
    constructor() {}

    ngOnInit() { setTimeout(() => { this.voiceInstructionService.setInstruction('test'); }, 3000); }
} 

我可以看到&#34;测试&#34;在Home和Recipes组件中记录,但如果我从Home或Recipe组件中设置了setInstruction(),它就不会发生相同的情况。难道这种配置不允许我在兄弟姐妹之间进行通信吗?该服务是在最高级别提供的。

1 个答案:

答案 0 :(得分:0)

您涉及路由,或者更确切地说两个组件同时不在视图中。 Subject需要next才能触发订阅。因此,当您在一个组件中调用next,而另一个组件不在视图中并导航到另一个组件时,订阅将不会触发。

您可以使用的是BehaviorSubject。如果有订阅者,则BehaviorSubject始终会发出。因此,请将Subject更改为BehaviorSubject。同时为BehaviorSubject提供一个初始值,因为它需要一个。这应该有希望解决你的问题:)