使用Angular 2中的服务在组件之间发送数据
我试图使用服务在两个组件之间发送数据。但是,我在第一次加载'child'组件时遇到数据填充问题。使用Angular 2中的服务在组件之间发送数据
当您从release-list.component上的无序列表中选择'release'时,它将通过router-outlet加载release-detail.component。 release-detail.component应该显示发布者。
如果您选择一个版本,然后再次选择一个版本,它会起作用。但是在填充数据之前,我必须两次“加载”release-detail.component。我觉得我很接近,但我必须错过一些东西。任何帮助将不胜感激。
感谢
我已经提到既是previous question和Angular documentation
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]);
}
}
release-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;
});
}
}
我想问题可能是你的Subject
发布它的价值你订阅它的ReleaseDetailComponent
内部之前。当您第二次执行此操作时,会发布一个新的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在订阅返回对象的最后一个值,因此postponely加载的组件将始终与最近的值进行更新:在行动BehaviorSubject
@Injectable
export class ReleaseService {
releaseSource: BehaviorSubject = new BehaviorSubject(null);
// No difference when it comes to subscribing to the BehaviorSubject
}
基本例如:Angular 2 Interaction between components using the service
我认为你是混合这里有两个概念。有两种方法可以做到这一点:
- 在释放细节分量声明的
release
与@Input
并从释放名单通过。你可以随意使用它作为组件中的变量。没有主题,没有订阅。 - 您使用上述服务,但您已经加载了详细信息。就像将它嵌入到发布列表html中,但是
*ngIf
设置为false,不会显示它。当您将所选版本放入主题中时,它会启动,然后您可以将*ngIf
设置为true,以显示版本详细信息部分。
辉煌。谢谢,Fredrik! RxJS的概念对我来说还是新的,所以我有一种感觉,那就是我会偏离轨道。我唯一需要改变的是在ReleaseDetailComponent和ngOnInit钩子 - > this.release = this._releaseService.getRelease()。subscribe(release => { return this.release = release; }); – bmd
完成!并再次感谢 – bmd
乐意帮忙! :) –