使用发出和订阅的跨组件通信不起作用

Cross Component communication using emit and subscribe not working

我想在父组件中使用事件发射器和订阅。

这是我的服务代码

@Injectable()
export class RecipeService{
    recipeselected= new EventEmitter<string>() ;
}

这是我使用事件发射器的代码。

onselected 函数有效

@Component({
  selector: 'app-receipie-item',
  templateUrl: './receipie-item.component.html',
  styleUrls: ['./receipie-item.component.css'],
  providers:[RecipeService]
})
export class ReceipieItemComponent implements OnInit {
  @Input() recipe:ReceipieModel ;//custom property
 
  constructor(private recipeservice:RecipeService) { }

  ngOnInit(): void {
  }

  onselected(){
    this.recipeservice.recipeselected.emit("hello");
    // console.log('hello');
  }  

}

这是我用过的代码,订阅事件。

问题是它在订阅中不起作用。

@Component({
  selector: 'app-receipies',
  templateUrl: './receipies.component.html',
  styleUrls: ['./receipies.component.css'],
  providers:[RecipeService]
})
export class ReceipiesComponent implements OnInit {
  selectedrecipe:ReceipieModel;
  constructor(private recipeservice:RecipeService) { 

  }

  ngOnInit() {
    this.recipeservice.recipeselected.subscribe(
      recipe=>{ 
        console.log(recipe);
      }
    );
  }

  
}

在服务中使用 EventEmitter 有什么具体原因吗? EventEmitter 是 RxJS Subject 的 Angular 特定扩展,旨在与 @Output 装饰器一起用于数据共享 b/n 兄弟组件。 RxJS Subject 的订阅者只会收到在订阅 之后 发出的通知。

如果组件不相关,并且如果您希望在将值推送到可观察对象后将来获取发射,您最好使用 BehaviorSubjectReplaySubject.

我将举例说明使用 ReplaySubject 和缓冲区 1。它可以“hold/buffer”最后发出的值,并会在将来发送给订阅者。

服务

import { Observable, ReplaySubject } from 'rxjs';

@Injectable()
export class RecipeService{
  private recipeSelected: ReplaySubject<string> = new ReplaySubject<string>(1);  // <-- buffer 1
  public recipeSelected$: Observable<string> = this.recipleSelected.asObservable();

  public setSelected(recipe: string): void {
    this.recipleSelected.next(recipe);
  }
}

组件 1(发件人)

onselected(){
  this.recipeservice.setSelected("hello");
}  

组件 2(收件人)

ngOnInit() {
  this.recipeservice.recipeSelected$.subscribe(
    recipe => { 
      console.log(recipe);
    }
  );
}

你搞混了。

要么像这样使用 Service 定义一个 Observable:

  private _subject$: Subject<string> = new Subject<string>();

  get subject$(): Subject<string> {
    return this._subject$;
  }

  // emit new data
  this.yourService.subject$.next('new data');

然后,在你要接收数据的组件中:

this.yourService.subject$.subscribe(data => { console.log(data) }

或使用 EventEmitter

  // componentA.ts
  @Output() public onDataChanged: EventEmitter<Array<EventItem>> = new EventEmitter();

  // publish new data
  public dataChanged() {
    this.onDataChanged.emit('new data')
  }

  // any other component, using your 'app-componentA'
  <app-componentA
      (dataChanged)="receivingMethod($event)">
  </app-componentA>

这里有一些文献:

https://angular.io/api/core/EventEmitter