Отправить событие Из сервисов Angular - PullRequest
0 голосов
/ 17 июня 2020

Comp onet Code

import { Component, OnInit, EventEmitter, Output, Input } from '@angular/core';
import { Socket } from 'ngx-socket-io';
import { CommonService } from 'src/app/services/common.service';
import { FormioService } from 'src/app/services/formio.service';
@Component({
  selector: 'app-initialrecord',
  templateUrl: './initialrecord.component.html',
  styleUrls: ['./initialrecord.component.sass']
})
export class InitialRecordComponent implements OnInit {
  form: any = "";
  rendered = false;
  showForm: any = false;
  showTable: any = false;
  showAdd: any = true;
  showClose: any = false;
  patientData: any = {};
  currentTab = "";
  submitFunction = 'onSubmit';
  formId: any = ''
  rows: any = [];
  cols: any = [];
  formioJson: any;
  patientid = "";
  patientName = ""
  @Output() refreshForm = new EventEmitter();
  @Input() patientDetails: any = {};
  constructor(
    private FormioService: FormioService,
    private commonService: CommonService,
    private socket: Socket ) { }

  ngOnInit() {
    this.patientid=JSON.parse(this.commonService.getValue("patientDetails"))._id
    this.patientName =JSON.parse(this.commonService.getValue("patientDetails")).data.fname
    this.formioJson = JSON.parse(sessionStorage.getItem("formioJson"));
    this.listFormData('vitals')
  }

  listFormData(formName: string) {
    this.formId = formName;
    this.rows = [];
    this.cols = []
    this.toggleView(true, false, true, false)
    this.currentTab = this.formioJson[formName].name;
    let path = this.formioJson[formName].path
    let fromName = this.formioJson[formName].name
    this.FormioService.loadForms(path).subscribe(data => {
      this.FormioService.checkNested(data, true);
      this.cols = this.FormioService.cols;
    })
//calling service function
    this.FormioService.getFormData(path, formName, this.patientid, "data.patientId")
// subscribe the event
    this.FormioService.receivedRow.subscribe((param: any) => {
      this.rows = param.row;
      this.patientData[this.formioJson[formName].name] = param.data;
    });
  }

}

сервисный код

import { Injectable , EventEmitter} from '@angular/core';
import { Socket } from 'ngx-socket-io';
import { environment } from '../../environments/environment';
import { ToastrService } from 'ngx-toastr';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { CommonService } from 'src/app/services/common.service';
import  moment from 'moment';

@Injectable({
  providedIn: 'root'
})
export class FormioService {
  headers: any;
  row :any[];
  cols:any[];
  receivedRow: EventEmitter<any>;
  patientData: any ={};
  constructor(private socket: Socket, private toaster: ToastrService,
    private httpClient: HttpClient,private commonService: CommonService) {
      this.receivedRow = new EventEmitter<any>()
      this.headers = new HttpHeaders({'Content-Type':'application/json; charset=utf-8','x-jwt-token':this.commonService.getValue("formioToken")})
     }
  public FORMIO_BASE_URL = environment.formioBaseUrl;
  public SOCKET_IO_URL = environment.nodeServerUrl


  getFormData(formUrl: string, tabName: string, patientId: string,keyName:string) {
    let form: any = new Object();
    form.roomId = this.commonService.roomId();
    form.token = this.commonService.getToken();
    form.eventName = tabName;
    form.formId = formUrl;
    form.query = keyName+"=" + patientId
    this.socket.emit('list', form);
    this.socket.on(tabName, async data => {
      this.row=[]
      data.forEach(element => {
        element.data['date'] =moment(element.created).format('DD-MM-YY HH:mm');
        console.log( element.data['date'] =moment(element.created).format('DD-MM-YY HH:mm'))
        this.row.push(element.data);
      });
      this.receivedRow.emit({row:this.row,data:data})
      console.log(this.row,"Formioservice")
    });
  }
  checkNested(obj: any,flag) {
    if(flag){
      this.cols =[]
      this.cols.push(JSON.parse( '{"field":"date","header":"Date"}'))
    }
    for (let prop in obj) {
      if (obj.hasOwnProperty(prop)) {
        if (typeof obj[prop] == "object") {
          //console.log('Key: ${prop}')
          this.checkNested(obj[prop],false);
        } else {
          //console.log("key >>> " + key + " >> props >>> " + obj[prop]);
          if (obj['tableView']) {
            //  console.log(`Key: ${prop} 'key_value: ${obj['key']} 'label_value: ${obj['label']} 'table_view_value: ${obj['tableView']} `)
            let temp: string = '{"field":"' + obj['key'] + '","header":"' + this.capitalize(obj['label']) + '"}';
            //  console.log(JSON.parse(temp));
            this.cols.push(JSON.parse(temp));
            break;
          }
        }
      }
    }

  }
  capitalize = (s: any) => {
    if (typeof s !== 'string') return ''
    return s.charAt(0).toUpperCase() + s.slice(1)
  }
}


при чтении этой ссылки может знать, что использование eventemitter в сервисах не является хорошей практикой .Приведенный выше код отлично работает, моя проблема в том, что у меня есть общая функция для formData, которая выбирает значение формы, зависящее от значения tabclick. 1-е событие времени излучается, как ожидалось, когда щелкает другую вкладку, то есть второй щелчок его испускает два раза, когда в третий раз он испускает 3 умножить на 4 означает, что 4 раза кто-нибудь может предложить мне лучший подход, к которому я не могу angular

1 Ответ

1 голос
/ 17 июня 2020

Вы инициируете новую подписку каждый раз, когда вызывается функция listFormData. Вместо этого вы можете подписаться на хук ngOnInit() один раз.

ngOnInit() {
  this.patientid=JSON.parse(this.commonService.getValue("patientDetails"))._id
  this.patientName =JSON.parse(this.commonService.getValue("patientDetails")).data.fname
  this.formioJson = JSON.parse(sessionStorage.getItem("formioJson"));
  this.listFormData('vitals')
  // subscribe the event
  this.FormioService.receivedRow.subscribe((param: any) => {
    this.rows = param.row;
    this.patientData[this.formioJson[formName].name] = param.data;
  });
}

listFormData(formName: string) {
  this.formId = formName;
  this.rows = [];
  this.cols = []
  this.toggleView(true, false, true, false)
  this.currentTab = this.formioJson[formName].name;
  let path = this.formioJson[formName].path
  let fromName = this.formioJson[formName].name
  this.FormioService.loadForms(path).subscribe(data => {
    this.FormioService.checkNested(data, true);
    this.cols = this.FormioService.cols;
  });
  //calling service function
  this.FormioService.getFormData(path, formName, this.patientid, "data.patientId");
}

Также, как вы упомянули в вопросе, EventEmitter не разработан как реализация Angular specifici c наблюдаемой многоадресной рассылки. Его цель - предоставить пользовательские события компонентам с отношениями родитель-потомок.

Если вы посмотрите на источник EventEmitter, это расширение интерфейса Rx JS Subject. Поэтому, если нам требуется наблюдаемая многоадресная рассылка в службе, мы могли бы использовать ее напрямую.

Служба

import { Injectable} from '@angular/core';

import { Subject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class FormioService {
  ...
  receivedRowSource = new Subject<any>();
  receivedRow$ = this.receivedRowSource.asObservable();

  getFormData(formUrl: string, tabName: string, patientId: string,keyName:string) {
    ...
    this.socket.on(tabName, async data => {
      ...
      this.receivedRowSource.next({row:this.row,data:data});       // <-- use `next` to push new notification
    });
  }
}

Вам также необходимо закрыть все активные подписки при закрытии компонента, чтобы избежать потенциальной памяти утечки. Вы можете вызвать присвоение подписки переменной-члену вызовом unsubscribe() в ловушке ngOnDestroy() или использовать оператор Rx JS takeUntil().

import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

export class InitialRecordComponent implements OnInit, OnDestroy {
  ...
  completed$ = new Subject<any>();

  ngOnInit() {
    this.FormioService.receivedRow$.pipe(
      takeUntil(this.completed$)        // <-- pipe in the `takeUntil()` here
    ).subscribe((param: any) => {
      this.rows = param.row;
      this.patientData[this.formioJson[formName].name] = param.data;
    });
  }

  ngOnDestroy() {
    this.completed$.next();
    this.completed$.complete();
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...