使用Angular 2中的服务在组件之间发送数据 [英] Sending data between components using a service in Angular 2
问题描述
我正在尝试使用服务在两个组件之间发送数据.但是,当子"组件首次加载时,我无法填充数据.
I'm trying to send data between two components using a service. However, I'm having trouble with the data populating when the 'child' component first loads.
当您从release-list.component的无序列表中选择一个"release"时,它将通过路由器出口加载release-detail.component. release-detail.component应该显示发布艺术家.
When you select a 'release' from the unordered list on the release-list.component, it will load the release-detail.component through a router-outlet. The release-detail.component should show the release artist.
如果您选择一个发行版,然后再次选择一个发行版,它将起作用.但是在填充数据之前,我必须两次加载" release-detail.component.我觉得我已经接近了,但我一定想念一些东西.任何帮助将不胜感激.
It works if you select a release and then select a release for a second time. But I'm having to 'load' the release-detail.component twice before the data is populated. I feel I'm close but I must be missing something. Any help would be greatly appreciated.
谢谢
release.service.ts
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);
}
}
release-list.component.ts
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
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
-这意味着它将起作用.
I think the problem could be that your Subject
publishes its value before you are subscribing to it inside your ReleaseDetailComponent
. When you do it the second time, a new Release
is published, and the ReleaseDetailComponent
is already created - meaning it will work.
要解决此问题,您可以尝试在服务中使用BehaviorSubject
而不是常规的Subject
. BehaviorSubject
将为您提供最新的发布值,即使您在最后一个值发布后订阅了它.不过,它也需要一个默认值,因此您可能要在ReleaseDetailComponent
模板中添加一些空检查.
To fix this, you can try to use a BehaviorSubject
instead of a regular Subject
in your service. The BehaviorSubject
will give you the latest published value even if you subscribe to it after the last value was published. It also expects a default value though, so you might want to add some null-checking in your ReleaseDetailComponent
template.
一个实现可能看起来像这样:
An implementation could look something like this:
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
,或者根据需要设置其他值.
And in your template, att null checking, as the default value we set to the BehaviorSubject
is undefined
. Of course, you can set the default value (the values passed into the constructor of the BehaviorSubject
) to an empty Release
or something else if you wish.
template: `
<h3>Release Detail</h3>
<p>{{ release?.artist }}</p> <!-- Note the '?' -->
`,
如果您想进一步了解Subjects
的不同类型,请查看以下文档:
Here are the docs if you want to learn more about the different types of Subjects
:
我希望这会有所帮助!
I hope this helps!
这篇关于使用Angular 2中的服务在组件之间发送数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!