OnInit извлекает свойство Service, которое еще не загружено - PullRequest
0 голосов
/ 23 марта 2020

Я очень плохо знаком с Angular 2+ (около недели), и у меня есть проблема, связанная с наблюдаемой частью.

У меня есть эта служба:

export class GetProductsService {

  allProducts;

  constructor(private http: HttpClient) {
    this.http.get('https://jsonplaceholder.typicode.com/posts').subscribe({
      next: data => this.allProducts = data,
      error: err => console.log(err)
    });
  }

  getAllProducts() {
    return this.allProducts;
  }

В конструкторе я делаю запрос на получение некоторых поддельных «продуктов».

Продукты, которые я получаю, я храню в собственности, так что я могу легче использовать другие функции для свойства в будущем.

Теперь вот моя проблема:

У меня есть этот компонент

export class AllProductsComponent implements OnInit {

allProducts: any;

constructor(private http: HttpClient, private productsService: GetProductsService) {}

ngOnInit(): void {
    this.allProducts = this.productsService.getAllProducts();
  }


}

, который получает свойство products из ProductService OnInit, однако, учитывая, что оно является наблюдаемым, когда другой компонент пытается получить свойство allProducts, но оно еще не полностью загружено из наблюдаемого потока.

Как бы это решить, я вижу, что это частая проблема, поэтому я также прошу более общего понимания топи c. Я понимаю, что это асин c, и я понимаю, что это такое.

То, что я пробовал :

Я пытался просто заставить Service возвращать Observable вместо установки своего собственного состояния, однако тогда, когда я реализую функцию для удаления указанного c product, мне нужно сделать HTTP-вызов снова, вместо использования внутреннего состояния.

Большое вам спасибо за ваше время!

Ответы [ 2 ]

2 голосов
/ 23 марта 2020

Вместо этого вам следует возвращать наблюдаемое из службы, если вы хотите получать уведомления о возвращении ответа.

Вы можете кэшировать ответ по первому ответу, если хотите избежать повторного http-запроса в время жизни приложения.

import { of } from 'rxjs';
import { tap } from 'rxjs/operators';

export class GetProductsService {

  private cache = {
    allProducts;
  };

  constructor(private http: HttpClient) { }

  getAllProducts() {
    if (this.cache.allProducts) {
      return of(this.cache.allProducts);
    }

    return this.http.get('https://jsonplaceholder.typicode.com/posts').pipe(
      tap(response => this.cache.allProducts = response)
    );
  }
}

Затем вы должны подписаться на эту функцию в своем компоненте.

ngOnInit(): void {
  this.productsService.getAllProducts().subscribe(products => {
    this.allProducts = products;
  });
}

Примечание - это очень простая форма управления состоянием, и я имею продемонстрировал эту модель как способ помочь вам научиться работать с наблюдаемыми. Существуют более совершенные шаблоны и инструменты управления состоянием, с которыми вы столкнетесь вовремя.

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

Я использую службу API следующим образом:

@Injectable()
export class ApiService {
  constructor(
    private http: HttpClient
  ) { }

  private setHeaders(): HttpHeaders {
    const headersConfig = {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    };

//...

    return new HttpHeaders(headersConfig);
  }

  private formatErrors(errorResponse: any) {
    return Observable.throw(errorResponse.error);
  }

  get(path: string, params: any = {}): Observable<any> {
    return this.http.get(`${environment.api_url}${path}`, { headers: this.setHeaders(), params: params })
    .catch(this.formatErrors);
  }
}

И использую ее следующим образом в моем ItemService:

 query(itemSlug: string): Observable<{ items: Item[] }> {   
    return this.apiService
      .get('/items/' + itemSlug);
  }

И в моем контроллере я использую ItemService следующим образом:

this.itemsService.query(this.item.slug).subscribe(data => {
  this.items = data.items;
});

Для получения дополнительной информации об этом подходе см. https://github.com/gothinkster/angular-realworld-example-app

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...