簡體   English   中英

使用Angular 2中的服務在組件之間發送數據

[英]Sending data between components using a service in Angular 2

我正在嘗試使用服務在兩個組件之間發送數據。 但是,當“子”組件首次加載時,我無法填充數據。

當您從release-list.component的無序列表中選擇一個“ release”時,它將通過路由器出口加載release-detail.component。 release-detail.component應該顯示發行藝術家。

如果您選擇一個發行版,然后再次選擇一個發行版,它將起作用。 但是我必須在數據填充之前兩次“加載” release-detail.component。 我覺得我已經接近了,但是我一定想念一些東西。 任何幫助將不勝感激。

謝謝

我已經提到了上一個問題Angular文檔

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使用該服務的組件之間的交互

我認為您在這里混入兩個概念。 有兩種方法可以做到這一點:

  1. 在發布細節組件中,使用@Input聲明release ,然后從發布列表中傳遞它。 您將可以使用它作為組件中的變量。 沒有主題,沒有訂閱。
  2. 您使用上面的服務,但是您已經加載了詳細信息。 就像將其嵌入發布列表html中一樣,但是將*ngIf設置為false,則不顯示它。 當您將選定的發行版放到主題中時,它將開始,然后您可以將*ngIf設置為true,顯示發行版詳細信息部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM