Передача данных между компонентами с использованием сервиса Angular - PullRequest
0 голосов
/ 16 октября 2018

В Интернете есть много примеров на эту тему, но ни один из них не помог мне.Это сценарий: у меня есть 2 компонента и сервис.Два компонента не являются родительскими / дочерними, но являются 2 независимыми компонентами.У одного из них есть список имен, другой должен загружать таблицу при нажатии на одно из имен.Это мой home.html с обоими компонентами

<div class="material-docs-app">
  <div class="docs-primary-header">
      <h1>Yep!</h1>
  </div>
    <div fxLayout="row" fxLayout.xs="column" class="component-layout-body">
        <app-heroes-sidenav></app-heroes-sidenav>
        <app-heroes-table #heroesTable fxFlex="1 2 calc(15em + 20px)" style="width: 100%"></app-heroes-table>
    </div>
</div>

Герои sidenav компонент:

<div *ngIf="loadingData == true">
  <mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>
<nav *ngIf="loadingData == false">
  <p *ngFor="let item of heroesNames.results let i = index" [attr.data-index]="i">
    <button mat-button (click)="getHero(i)">
        {{item.name}} 
    </button>
  </p>
</nav>

При нажатии getHero() вызывается правильно.Это sidenav компонент ts:

import { Component, OnInit, Input } from '@angular/core';
import {SwCharactersServiceService} from '../sw-characters-service.service';
import {HeroesTableComponent} from '../heroes-table/heroes-table.component';

@Component({
  selector: 'app-heroes-sidenav',
  templateUrl: './heroes-sidenav.component.html',
  styleUrls: ['./heroes-sidenav.component.css']
})
export class HeroesSidenavComponent implements OnInit {
  heroesNames: any;
  heroData:any;
  loadingData = true;
  @Input() heroesTable: HeroesTableComponent;
  constructor(private _swService: SwCharactersServiceService) { }

  ngOnInit() {
    this.getHeroes();
  }

  getHeroes() {
    this._swService.getCharacters().then(result => {
      this.loadingData = false;
      this.heroesNames = result;
    });
  }

  getHero(index) {
    this._swService.getHero(index);
  }
}

, а это сервис:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import 'rxjs/add/operator/map'

import {Observable} from 'rxjs/Observable';

@Injectable({
  providedIn: 'root'
})
export class SwCharactersServiceService {
  param:any;
  constructor(private http: HttpClient) { }

  getCharacters(): Promise<any[]> {
    return this.http.get<any[]>("https://swapi.co/api/people/")
    .toPromise()
    .then(result => result) 
    .catch(this.handleError);
  }

  getHero(index): Observable<any>{
    console.log(index);
    let headers = new HttpHeaders();
    headers.append('Content-Type', 'application/json');
    return this.http.get("https://swapi.co/api/people/" + index, {
        headers: headers
    }).map(res => res );
  }

  private handleError(error: any): Promise<any> {
    console.error('An error occurred', error); // for demo purposes only
    return Promise.reject(error.message || error);
  }
}

Я могу правильно видеть console.log(index), но запрос не работает.На вкладке сети консоли Chrome нет запроса.Это компонент с таблицей:

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import {SwCharactersServiceService} from '../sw-characters-service.service';

@Component({
  selector: 'app-heroes-table',
  templateUrl: './heroes-table.component.html',
  styleUrls: ['./heroes-table.component.css']
})
export class HeroesTableComponent implements OnInit {
  loadingData = true;
  heroData :any;
  subscription: Subscription;

  constructor(private _swService: SwCharactersServiceService) {
    this.subscription = this._swService.getHero(1).subscribe(result => { this.heroData = result; });
    console.log(this.heroData);
  }

  ngOnInit() {

  }

  ngOnDestroy() {
    // unsubscribe to ensure no memory leaks
    this.subscription.unsubscribe();
  }
}

Сейчас есть 2 проблемы:

1) Как вы можете видеть, я написал this._swService.getHero(1) без передачи динамического параметра.Как это работает?Как я могу передать правильный индекс?

2) Служба не работает, и у меня нет никакого результата.

Есть ли другой способ сделать это?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Вы можете использовать BehaviourSubject для передачи значения индекса и отправки запроса на запрос, когда список кликается в сервисе

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 public index: BehaviorSubject<number> = new BehaviorSubject<number>(null);

в компоненте sidenav

getHero(index) {
    this._swService.index.next(index);
  }

в героекомпонент таблицы

ngAfterViewInit(){
   this._swService.index.subscribe(index=>{
      if(index){
        this._swService.getHero(index).subscribe(result => { this.heroData = result; });
      }
   })
}
0 голосов
/ 16 октября 2018

Вы пропустили подписку на _swService.getHero().Если не подписан на метод, который возвращает Observable, он не будет вызван.

getHero(index) {
    this._swService.getHero(index).subscribe(
                  (resp) => {
                     // manipulate your response here
                     console.log(resp);  
                  },
                  (err) => {}
          );
}
...