[英]Sending data between components using a service in Angular 2
我正在嘗試使用服務在兩個組件之間發送數據。 但是,當“子”組件首次加載時,我無法填充數據。
當您從release-list.component的無序列表中選擇一個“ release”時,它將通過路由器出口加載release-detail.component。 release-detail.component應該顯示發行藝術家。
如果您選擇一個發行版,然后再次選擇一個發行版,它將起作用。 但是我必須在數據填充之前兩次“加載” release-detail.component。 我覺得我已經接近了,但是我一定想念一些東西。 任何幫助將不勝感激。
謝謝
release.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { MockReleaseList, ReleaseInterface } from './mock-releases';
@Injectable()
export class ReleaseService {
private releaseSubject$ = new Subject();
getReleases(): ReleaseInterface[] {
return MockReleaseList;
}
getRelease() {
return this.releaseSubject$;
}
updateRelease(release: {artist: string, title: string, category: string}[]) {
// console.log(release);
this.releaseSubject$.next(release);
}
}
釋放-list.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Location } from '@angular/common';
import { ReleaseService } from '../../../shared/services/release.service';
import { MockReleaseList, ReleaseInterface } from '../../../shared/services/mock-releases';
@Component({
selector: 'ostgut-releases',
template: `
<h3>Label List</h3>
<ul>
<li *ngFor="let release of releases" (click)="onSelect(release)">{{ release.artist }}</li>
</ul>
<router-outlet></router-outlet>
`,
})
export class ReleaseListComponent implements OnInit {
private releases: ReleaseInterface[];
constructor (
private _router: Router,
private _releaseService: ReleaseService
) {}
ngOnInit(): ReleaseInterface[] {
return this.releases = this._releaseService.getReleases();
}
onSelect(release: any): void {
this._releaseService.updateRelease(release);
this._router.navigate(['/release-list/release-detail', release.category]);
}
}
釋放-detail.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { ReleaseService } from '../../../../shared/services/release.service';
import { ReleaseInterface } from '../../../../shared/services/mock-releases';
@Component({
selector: 'ostgut-release-detail',
template: `
<h3>Release Detail</h3>
<p>{{ release.artist }}</p>
`,
})
export class ReleaseDetailComponent implements OnInit {
private routeParam: string;
private routeParamSub: any;
private release: any;
constructor(
private _activatedRoute: ActivatedRoute,
private _router: Router,
private _releaseService: ReleaseService
) {}
ngOnInit(): void {
this.release = this._releaseService.getRelease().subscribe(release=>{
return this.release = release;
});
}
}
我認為問題可能出在您在ReleaseDetailComponent
內訂閱它之前,您的Subject
發布其值。 當您第二次執行此操作時,將Release
一個新的Release
,並且已經創建了ReleaseDetailComponent
這意味着它將起作用。
要解決此問題,您可以嘗試在服務中使用BehaviorSubject
而不是常規Subject
。 BehaviorSubject
將為您提供最新的發布值,即使您在發布最后一個值后訂閱它也是如此。 不過,它也需要一個默認值,因此您可能需要在ReleaseDetailComponent
模板中添加一些空檢查。
一個實現可能看起來像這樣:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; // <-- note the import!
import { MockReleaseList, ReleaseInterface } from './mock-releases';
@Injectable()
export class ReleaseService {
private releaseSubject$ = new BehaviorSubject(undefined);
// The rest is the same
}
在您的模板中,請進行att空檢查,因為我們設置為BehaviorSubject
的默認值為undefined
。 當然,您可以將默認值(傳遞給BehaviorSubject
的構造函數的值)設置為空的Release
或者根據需要設置其他值。
template: `
<h3>Release Detail</h3>
<p>{{ release?.artist }}</p> <!-- Note the '?' -->
`,
如果您想進一步了解不同類型的Subjects
以下文檔:
我希望這有幫助!
考慮使用BehaviorSubject
作為委托。 訂閱時的BehaviorSubject返回主題的最后一個值,因此,延遲加載的組件將始終使用最新值進行更新:
@Injectable
export class ReleaseService {
releaseSource: BehaviorSubject = new BehaviorSubject(null);
// No difference when it comes to subscribing to the BehaviorSubject
}
正在運行的BehaviorSubject
基本示例: Angular 2使用該服務的組件之間的交互
我認為您在這里混入兩個概念。 有兩種方法可以做到這一點:
@Input
聲明release
,然后從發布列表中傳遞它。 您將可以使用它作為組件中的變量。 沒有主題,沒有訂閱。 *ngIf
設置為false,則不顯示它。 當您將選定的發行版放到主題中時,它將開始,然后您可以將*ngIf
設置為true,顯示發行版詳細信息部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.