Шаблоны доступа к данным для 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
Вам нужно узнать, как работают асинхронность и наблюдаемые. Вы не подписаны на сервис. Вы возвращаете наблюдаемое из сервиса и подписываетесь на него в компоненте (или в представлении с асинхронным каналом). У вашего сервиса нет причин иметь какое-либо свойство, кроме 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