0

我有一个 listComponent、一个 detailsComponent 和一个 componentsCommunication 服务。我正在使用 router.navigate 从列表转到详细信息组件,并且我正在尝试通过 componentsCommunicationService 传递数据。

通信服务组件代码:

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() { }

}

我的列表组件代码:

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 总是未定义的。

另一种解决方案是将 id 作为参数传递并重新执行 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 是未定义的...所以它不会从订阅中读取数据。

4

1 回答 1

0

您的代码未显示您声明 ComponentsCommunicationService 提供程序的位置。确保它仅在一个地方声明 - 在您的根应用程序 @NgModule 中。这样,列表组件(数据生产者)和详细组件(消费者)都使用相同的 ComponentsCommunicationService 实例。

于 2017-08-21T14:24:32.323 回答