使用 Angular 2 中的服务在组件之间发送数据 [英] Sending data between components using a service in Angular 2

查看:26
本文介绍了使用 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.

谢谢

我已经提到了上一个问题Angular 文档

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 null 检查,作为我们为 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:

我希望这会有所帮助!

这篇关于使用 Angular 2 中的服务在组件之间发送数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆