Модели за достъп до данни за Angular

Боря се с асинхронни модели за достъп до данни в приложение Angular 8 (идва от .NET). Използвам компоненти, услуги за достъп до данни и персонализирани класове, които действат върху данните от услугите. Изглежда, че трябва да инжектирам моите услуги за достъп до данни в моите компоненти - но къде мога да използвам персонализираните си класове за бизнес логика?

Какво бих искал:

КОМПОНЕНТ:

import { Component, OnInit } from '@angular/core';
import { SampleService } from '../services/sample.service';
import { CustomBusinessLogic } from '../../cbl'; 


@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss']
})
export class Example implements OnInit {

  constructor(private sampleService: SampleService) { }

  ngOnInit() { }

  doSomething() {

    const dataToActOn = this.sampleService.getDataToActOn();

    // Do something with dataToActOn here

      const p = new CustomBusinessLogic.Calculator(
        dataToActOn.params as Settings,
        dataToActOn.data1,
        dataToActOn.data2
      );

      const res = p.calculate();
  }
}

ОБСЛУЖВАНЕ:

import { Injectable } from '@angular/core';
import { ExampleDataService } from './data/example-data.service';
import { SettingsService } from './data/settings.service';
import { forkJoin } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class SampleService {

  data1: any[];
  data2: any[];
  params: [];

  constructor(private projections: ,
    private data: ExampleDataService, private settingsService: SettingsService) { }


  loadDataHttp() {

    const id = 'for-testing';
    const b = this.data.getDataSet1(new Date());
    const p = this.data.getDataSet2(new Date());
    const m = this.settingsService.getDataSet3(id, 2018);

    return forkJoin([b, p, m]);

  }

  getDataToActOn() {

    this.loadDataHttp().subscribe(data => {
      this.data1 = data[0];
      this.data2 = data[1];
      this.params = data[2];

      // HOW DO I RETURN THIS DATA TO THE COMPONENT 
      // AND HAVE IT AVAILABLE TO MY CUSTOM BUSINESS LOGIC??

    });
  }
}

Моят проблем (в този псевдо/примерен код) е, че когато компонентът ми стигне до new CustomBusinessLogic.Calculator, нито една от данните все още не се е върнала от услугата.

Как мога да преструктурирам това, така че да мога да действам върху данни, върнати от услуги в моите компоненти или в други услуги?

Благодаря ти!


person Kevin    schedule 06.09.2019    source източник
comment
Трябва да научите как работят асинхронността и наблюдаемостта. Не се абонирате за услугата. Връщате наблюдаем от услугата и се абонирате за него в компонента (или в изгледа с async pipe). Вашата услуга няма причина да има собственост, различна от httpClient. Документацията на Angular има цели глави, посветени на това.   -  person JB Nizet    schedule 07.09.2019


Отговори (2)


Променете това:

getDataToActOn() {
   this.loadDataHttp().subscribe(data => {
    this.data1 = data[0];
    this.data2 = data[1];
    this.params = data[2];
    // What now?
});

}

Към това в услугата:

getDataToActOn() {
   return this.loadDataHttp();
}

Променете и това:

doSomething() {

    const dataToActOn = this.sampleService.getDataToActOn();

    // Do something with dataToActOn here

    const p = new CustomBusinessLogic.Calculator(
        dataToActOn.params as Settings,
        dataToActOn.data1,
        dataToActOn.data2
    );

   const res = p.calculate();
}

Към това в компонента:

doSomething() {
   this.sampleService.getDataToActOn().subscribe(
        (dataToActOn) => {
            const p = new CustomBusinessLogic.Calculator(
                dataToActOn.params as Settings,
                dataToActOn.data1,
                dataToActOn.data2
            );
            const res = p.calculate();
        }
    );
}

Съжалявам, ако форматирането е малко прецакано.

GetDataToActOn сега очевидно е малко тънък. Бихте използвали този метод, за да предавате нормално аргументи, опции и заглавки на http услугата.

person IanT8    schedule 07.09.2019

Трябва да върнете Observable в getDataToActOn функция във вашата услуга.

Така че функцията трябва да бъде като следната.

getDataToActOn() {
    return this.loadDataHttp().pipe(map(data => ({
        data1: data[0],
        data2: data[1],
        params: data[2]
    })));
}

Проверете тук, ако желаете да проучим задълбочено RxJS pipe и map.

И след това абонирайте данните от вашия компонент с

this.sampleService.getDataToActOn().subscribe(dataToActOn => {

    const p = new CustomBusinessLogic.Calculator(
      dataToActOn.params as Settings,
      dataToActOn.data1,
      dataToActOn.data2
    );

    const res = p.calculate();

});
person Julian Liu    schedule 07.09.2019
comment
Вашият съвет да върнете наблюдаема е добър, но вашият код не връща наблюдаема. - person JB Nizet; 07.09.2019