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

查看:50
本文介绍了使用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空检查,因为我们设置为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屋!

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