メインコンポーネントでイベントを発行しています。
main.component.ts
this.sharedService.cartData.emit(this.data);
これが私のsharedService.tsです
import { Component, Injectable, EventEmitter } from '@angular/core';
export class SharedService {
cartData = new EventEmitter<any>();
}
私の他の(サブ)コンポーネントでは、この値にアクセスしたいのですが、どういうわけかサブスクリプションが機能しません。
dashboard.ts
private myData: any;
constructor(private sharedService: SharedService) {
this.sharedService.cartData.subscribe(
(data: any) => myData = data,
error => this.errorGettingData = <any>error,
() => this.aggregateData(this.myData));
}
何か不足していますか?データをInjectableとして渡すと正常に機能します。 (メインコンポーネントでの)イベントの発行は、REST呼び出しの後に発生します。
更新
したがって、問題は、イベントの最初の発行後にサブコンポーネントが作成されることです。この場合、データをsubcompnent
に直接注入する方が良いと思います。
更新:もうメンテナンスされていないPlunkerの例はこちらのStackBlitzの例を使用してください https://stackblitz.com/edit/stackoverflow-questions-45351598- angular?file = src%2Fapp%2Fapp.component.ts
上記で提供したコードを使用して、実用的なプランカーの例を作成しました。 https://plnkr.co/edit/LS1uqB?p=preview
import { Component, NgModule, Injectable, EventEmitter, AfterViewInit } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@Injectable()
export class SharedService {
cartData = new EventEmitter<any>();
}
@Component({
selector: 'app-app',
template: `
<h1>
Main Component <button (click)="onEvent()">onEvent</button>
</h1>
<p>
<app-dashboard></app-dashboard>
</p>
`,
})
export class App implements AfterViewInit {
data: any = "Shared Data";
constructor(private sharedService: SharedService) {
}
ngAfterViewInit() {
this.sharedService.cartData.emit("ngAfterViewInit: " + this.data);
}
onEvent() {
this.sharedService.cartData.emit("onEvent: " + this.data);
}
}
@Component({
selector: 'app-dashboard',
template: `
<h2>
Dashboard component
</h2>
<p>
{{myData}}
</p>
`,
})
export class AppDashboard implements AfterViewInit {
myData: any;
constructor(private sharedService: SharedService) {
this.sharedService.cartData.subscribe(
(data: any) => {
console.log(data);
this.myData = data;
});
}
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App, AppDashboard ],
providers: [ SharedService ],
bootstrap: [ App ]
})
export class AppModule {}
ここでライフサイクルフックを表示 https://angular.io/guide/lifecycle-hooks
これを試して:
export class SharedService {
private dataPusher = new Subject<any>();
cartData = dataPusher.asObservable().pipe(shareReplay(1));
pushData(value:any) {
this.dataPusher.next(value);
}
}
それは、「遅延」サブスクライバーに対して最後に発行された値を再生するということです。初期値を出力したい場合は、BehaviourSubject
を使用できます。コンストラクタで初期値を取得します。
または、startWith
演算子でパイプ/チェーンすることもできます。
cartData = dataPusher.asObservable().pipe(startWith("someValue"), shareReplay(1));