Считать объекты наблюдаемого в сервисе в Angular - PullRequest
0 голосов
/ 18 марта 2020

card.service.ts

@Injectable({
providedIn: 'root'
})

export class CardService {
drugs: Drugs = [];

public objObservable: any;
private objObserver: any;

constructor() {
    this.objObservable = new Observable((localObserver) => {
        this.objObserver = localObserver; // Convert this.objObserver from any to an observer object
        this.objObserver.next(this.drugs); // Connect this.drugs to observable object by observer
    });
}

getDrugs(): Observable<Drugs> {
    return this.objObservable;
}

addDrug(newDrug: Drug) {
    this.drugs = [...this.drugs, newDrug];
    return this.objObserver.next(this.drugs);
}

removeDrug(neo4jId: string) {
    this.drugs = this.drugs.filter((item: Drug) => item.neo4jId !== neo4jId);
    return this.objObserver.next(this.drugs);
}

Я использую этот сервис для добавления и удаления некоторых лекарств в наблюдаемую в моем домашнем компоненте. В компоненте карты я хочу l oop в этом Observable и выдать значения, которые мне нужно показать в html.

card.component. html

<div>
{{  this.cardService.getDrugs() | async | json }}
</div>

этот дает мне весь вывод наблюдаемого как json, а затем я попытался сделать что-то вроде

<div>
{{  (this.cardService.getDrugs() | async | json).type }}
</div>

, чтобы показать мне только тип, но это не работает. Как может il oop через все Объекты в этой наблюдаемой и выводить только типы fe?

Модель снадобья:

export interface Drug {

neo4jId?: string;
drugId?: string;
tradingName: string;
type: string;
quantity: number;
expire: Date;
entryDate: Date;
lastModified?: Date;
slot: number;
substances?: Substance[]
};

export interface Drugs extends Array<Drug> { }

Ответы [ 3 ]

0 голосов
/ 18 марта 2020

Я обычно использую BehaviorSubject для того, что вы пытаетесь выполнить sh. Посмотрите, работает ли это для вас. Вы можете проверить рабочий пример здесь https://stackblitz.com/edit/ng-service-behaviorsubject

import { Injectable } from '@angular/core'
import { BehaviorSubject, Observable } from 'rxjs';

export interface Drug {
  neo4jId: string;
  Description: string;
}

@Injectable({
  providedIn: 'root'
})
export class CardService {
  private bsDrugs = new BehaviorSubject<Drug[]>([])

  constructor() {
  }

  getDrugs(): Observable<Drug[]> {
      return this.bsDrugs;
  }

  addDrug(newDrug: Drug) {
      let drugs = [...this.bsDrugs.value, newDrug];
      this.bsDrugs.next(drugs);
  }

  removeDrug(neo4jId?: string) {
    let drugs = [];
    if (neo4jId) {
      drugs = this.bsDrugs.value.filter((item: Drug) => item.neo4jId !== neo4jId);
    } else {
      if (this.bsDrugs.value.length > 0 ) {
        this.bsDrugs.value.pop();
        drugs = this.bsDrugs.value;
      }
    }

    this.bsDrugs.next(drugs);
  }
}
0 голосов
/ 18 марта 2020

Я решил проблему вот так

@Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.css']
})
export class CardComponent implements OnInit {
  drugList: Observable<Array<Drug>>;
  subscription: Subscription;

constructor(private cardService: CardService) { }

ngOnInit() {

 this.drugList = this.cardService.getDrugs();

}

}

, а в html

<div *ngFor="let drug of drugList | async">
  <p>{{   drug.tradingName    }}</p>
  <p>{{   drug.type  }}</p>
  <p>{{   drug.quantity  }}</p>
  <p>{{   drug.slot  }}</p>
</div>

стиль, конечно, можно улучшить. Моя точка зрения заключалась в том, как получить доступ к объектам в наблюдаемой

0 голосов
/ 18 марта 2020

Есть ли какая-то конкретная c цель для отделения drugs контейнера, и это можно наблюдать? Пожалуйста, проверьте, соответствует ли следующее требование

@Injectable({
 providedIn: 'root'
})
export class CardService {
 private drugsSource = new BehaviorSubject<Array<Drug>>([]);
 private drugs$ = this.drugsSource.asObservable();

 constructor() { }

 getDrugs(): any {
   return this.drugs$;
 }

 addDrug(newDrug: Drug) {
   this.drugsSource.next([...this.drugsSource.getValue(), newDrug]);
 }

 removeDrug(neo4jId: string) {
   this.drugsSource.next(this.drugsSource.getValue().filter((item: Drug) => item.neo4jId !== neo4jId));
 }
}

Нет смысла возвращать заметные объекты из метода добавления и удаления, когда есть отдельный метод get. Так что подписывайтесь на него всякий раз, когда вы добавляете или удаляете значения.

Компонент

this._cardService.addDrug(drug);
this._cardService.getDrugs().subscribe(drugs => { 
  // handle value 
});

// similarly for removing
this._cardService.removeDrug('34');
this._cardService.getDrugs().subscribe(drugs => { 
  // handle value 
});

Обновление Для отображения введите HTML, вам нужно написать конвейер.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'drugsType'
})
export class TypeOfPipe implements PipeTransform {

  transform(drugs: any): any {
    let result = [];
    for (const drug of drugs) {
      let obj = {};
      for (const key of Object.keys(drug)) {
        obj[key] = typeof drug[key];
      }
      result.push(obj);
    }
    return result;
  }

}

Рабочий пример: Stackblitz

...