Компоненты не взаимодействуют с помощью службы и маршрутизатора

У меня есть listComponent, detailsComponent и componentCommunication Service. Я использую router.navigate для перехода от списка к компоненту сведений, и я пытаюсь передать данные через компонентыCommunicationService.

Код компонента службы связи:

import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Incident} from '../../incidents/incident';
import {Patient} from '../../patients/patient';
import {Subject} from 'rxjs/Subject';

@Injectable()
export class ComponentsCommunicationService {

  private incidentsSubject = new BehaviorSubject<Incident[]>([]);
  private patientsSubject = new BehaviorSubject<Patient[]>([]);
  private incidentSubject = new Subject<Incident>();

  get incidentsData(): any { return this.incidentsSubject.value; }
  get patientsData(): any { return this.patientsSubject.value; }

  sendIncidentData(data: Incident){
    this.incidentSubject.next(data);
  }

  clearIncidentData(){
    this.incidentSubject.next();
  }

  getIncidentData(){
    return this.incidentSubject.asObservable();
  }

  sendIncidentsData(data: Array<any>) {
    this.incidentsSubject.next(data);
  }

  clearIncidentsData() {
    this.incidentsSubject.next([]);
  }

  getIncidentsData(): Observable<any> {
    return this.incidentsSubject.asObservable();
  }

  sendPatientsData(data: Array<any>) {
    this.patientsSubject.next(data);
  }

  clearPatientsData() {
    this.patientsSubject.next([]);
  }

  getPatientsData(): Observable<any> {
    return this.patientsSubject.asObservable();
  }

  constructor() { }

}

Мой код listComponent:

import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {IncidentsService} from '../incidents.service';
import {Incident} from '../incident';
import {Router} from '@angular/router';
import {HttpErrorResponse} from '@angular/common/http';
import {MdPaginator, MdSort} from '@angular/material';
import {ComponentsCommunicationService} from '../../shared/services/components-communication.service';
import {IncidentsDataSource} from '../../shared/lib/incidents-data-source';
import {Observable} from 'rxjs/Observable';

@Component({
  selector: 'app-incidents-list',
  templateUrl: './incidents-list.component.html',
  styleUrls: ['./incidents-list.component.css']
})
export class IncidentsListComponent implements OnInit {

  @ViewChild('paginator') paginator: MdPaginator;
  @ViewChild(MdSort) sort: MdSort;
  @ViewChild('filter') filter: ElementRef;

  incidentsDataSource: IncidentsDataSource | null;
  displayedColumns = ['protocolNo', 'date', 'patient', 'doctor', 'signingDoctor', 'clinic', 'isPayed', 'actions'];

  private incidents: Incident[] = [];
  private errorMsg;

  constructor(private incidentsService: IncidentsService, private router: Router, private comService: ComponentsCommunicationService) {

  }

  ngOnInit() {
    this.incidentsDataSource = new IncidentsDataSource(this.comService, this.paginator, this.sort);
    this.getIncidents();

    Observable.fromEvent(this.filter.nativeElement, 'keyup')
      .debounceTime(150)
      .distinctUntilChanged()
      .subscribe(() => {
        if (!this.incidentsDataSource) { return; }
        this.incidentsDataSource.filter = this.filter.nativeElement.value;
      });

  }

  showAndPrint(incident) {

    console.log("lakalka: " + JSON.stringify(incident));
    // this.comService.sendIncidentData(incident);
    this.router.navigate(["incidents/details"]);
    this.comService.sendIncidentData(incident);
    console.log("Exetuted Send Incident From List To Details");

  }

  editItem(event){
    console.log("lakfdfdasasalka: " + JSON.stringify(event));
  }

  deleteItem(event){
    console.log("delete: :  " + JSON.stringify(event));

  }

  getIncidents() {
    this.incidentsService.getIncidents()
      .catch( error => {
        // here we can show an error message to the user,
        // for example via a service
        console.log("error catched", error);

        return Observable.of({description: error});
      })
      .subscribe(
      (incidents) => {
        this.incidents = incidents;
        this.comService.sendIncidentsData(this.incidents);
      }
    );
  }

}

Мой код listComponent.html: я использую таблицу данных Angular Material 2

<div class="example-container mat-elevation-z8">

  <!--Filtering input fiels-->
  <div class="example-header">
    <md-input-container floatPlaceholder="never">
      <input mdInput #filter placeholder="Αναζήτηση">
    </md-input-container>
  </div>

  <md-table #table [dataSource]="incidentsDataSource" mdSort>

    <ng-container cdkColumnDef="protocolNo">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Αρ. Πρωτοκόλλου</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.protocolNo}}</md-cell>
    </ng-container>

    <ng-container cdkColumnDef="date">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Ημερομηνία</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.date | date:'dd/MM/yyyy' }}</md-cell>
    </ng-container>

    <ng-container cdkColumnDef="patient">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Ασθενής</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.patient.lastName}} {{row.patient.firstName}}</md-cell>
    </ng-container>

    <ng-container cdkColumnDef="doctor">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Ιατρός</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.doctor.lastName}} {{row.doctor.firstName}}</md-cell>
    </ng-container>

    <ng-container cdkColumnDef="signingDoctor">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Υπογράφων Ιατρός</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.signingDoctor.lastName}} {{row.signingDoctor.firstName}}</md-cell>
    </ng-container>

    <ng-container cdkColumnDef="clinic">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Κλινική</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.clinic?.name}}</md-cell>
    </ng-container>

    <ng-container cdkColumnDef="isPayed">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Πληρωμή</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.isPayed | payment}}</md-cell>
    </ng-container>

    <ng-container cdkColumnDef="actions">
      <md-header-cell *cdkHeaderCellDef> Ενέργειες</md-header-cell>
      <md-cell *cdkCellDef="let row" >

        <div style="display: inline-block;">

Здесь я передаю данные строки в функцию showAndPrint(). Данные передаются нормально, я вижу это с помощью console.log(row).

          <button md-button (click)="showAndPrint(row)" >
            <md-icon class="md-18">visibility</md-icon> εκτ
          </button>

          <button md-button (click)="editItem(row)"  style="display: inline-block;">
            <md-icon class="md-18">mode_edit</md-icon> επεξ
          </button>

          <button md-button (click)="deleteItem(row)"  style="display: inline-block;">
            <md-icon class="md-18">delete</md-icon> διαγ
          </button>

        </div>

      </md-cell>
    </ng-container>

    <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
    <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
  </md-table>

  <md-paginator #paginator
                [length]="incidentsDataSource.size"
                [pageIndex]="0"
                [pageSize]="10"
                [pageSizeOptions]="[10, 25, 50, 100]">
  </md-paginator>

</div>

Наконец, мой код DetailsComponent: здесь я пытаюсь подписаться на сервис и прочитать данные. Я оба пытаюсь подписаться в конструкторе и OnInit(). Однако this.incidents всегда не определено.

Другим решением было бы передать идентификатор в качестве параметра и повторно выполнить запрос http.get для получения сведений из базы данных, но, поскольку у меня уже есть данные из listComponent, я хотел бы передать его в компонент сведений без повторного выполнения. http-запрос. Это возможно??

import {Component, OnDestroy, OnInit} from '@angular/core';
import {ComponentsCommunicationService} from '../../shared/services/components-communication.service';
import {Incident} from '../incident';
import {Subscription} from 'rxjs/Subscription';

@Component({
  selector: 'app-incident-details',
  templateUrl: './incident-details.component.html',
  styleUrls: ['./incident-details.component.css']
})
export class IncidentDetailsComponent implements OnDestroy, OnInit {

  private incident: Incident;
  private subscription: Subscription;

  constructor(private commService: ComponentsCommunicationService){
    this.subscription = this.commService.getIncidentData().subscribe(incident => { this.incident = incident});
  }

  ngOnInit(): void {
    this.subscription = this.commService.getIncidentData().subscribe(incident => { this.incident = incident});
    console.log("Target: " + JSON.stringify(this.incident));
  }

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }

}

В detailsComponent this.incident не определен... Поэтому он не читает данные из подписки.


person mixtou    schedule 21.08.2017    source источник


Ответы (1)


Ваш код не показывает, где вы объявили поставщика для ComponentsCommunicationService. Убедитесь, что он объявлен только в одном месте — в вашем корневом приложении @NgModule. Таким образом, как компонент списка (производитель данных), так и компоненты сведений (потребители) используют один и тот же экземпляр ComponentsCommunicationService.

person Yakov Fain    schedule 21.08.2017
comment
Он объявлен в sharedModule, который я не включил. Служба найдена и выполнена, потому что я использую ее и в других компонентах связи. Проблема в том, что данные не передаются. - person mixtou; 21.08.2017