Как прослушать http-вызов в службе из компонента в angular?

Я только начинаю работать с angular, и мне нужна помощь в прослушивании новых http-вызовов в службе из компонента. Первоначально я извлекаю данные (возвращает массив) из вызова API через ngOnInit из content.component.ts, используя fetch-article.service Позже, когда updateID вызывается другим компонентом (sidebar.component.ts), он вызывает ту же функцию из fetch-article.service. Что я хочу сделать, так это то, что как только будет сделан новый http-запрос из fetch-article.service, переменная items в content.component.ts должна иметь значение вновь извлеченных данных.

content.component.ts:

export class ContentComponent implements OnInit {
  items = [];

  constructor(
    private fetchArticlesService: FetchArticlesService) {}

  ngOnInit() {
    this.getArticlesbyID('123')
    .subscribe(result => {
     console.info('test')
  });

  getArticlesbyID(id){
  return this.fetchArticlesService.fetchArticles(id).pipe(map(
    fetchArticlesService => {
      this.items = Object(fetchArticlesService);
    })
  )}
}

В моем fetch-article.service.ts у меня есть:

export class FetchArticlesService {

  fetchArticles(id) {
    return this.http.get('http://127.0.0.1:5000/query/' + id);
  }

  constructor(
    private http: HttpClient
  ) { }
}

sidebar.component.ts:

updateID(id) {
    this.fetchArticlesService.fetchArticles(id)
  }

Пожалуйста, помогите мне в этом. Я только начинаю работать с Angular. Стекблиц-код: https://stackblitz.com/edit/angular-vyotee

Итак, текущая проблема? Не получается добиться?

Prashant Pimpale 15.07.2019 08:43

да. Когда я визуализирую его в html, значение переменной 'items' остается прежним даже после выполнения функции fetchArticles() в сервисе.

Viktor1903 15.07.2019 08:45

Можете ли вы предоставить код Stackblitz, где я могу воспроизвести

Prashant Pimpale 15.07.2019 08:47
stackblitz.com/edit/angular-vyotee Когда я нажимаю кнопку, должны отображаться новые данные.
Viktor1903 15.07.2019 09:14

Я нашел два компонента: кнопку в компоненте боковой панели. И содержимое в компоненте содержимого. Если нажатие кнопки должно обновить содержимое, необходимо выполнить либо общий сервис, либо отправку идентификатора из компонента боковой панели.

Abishek ram R 15.07.2019 09:33

Пожалуйста, проверьте мой ответ - он также имеет рабочий стек.

Dino 15.07.2019 09:44
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
6
1 831
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы познакомились с предметами в angular? Я думаю, что это идеальный случай для субъекта.

Субъекты сами являются наблюдаемыми, но их отличает то, что они также являются наблюдателями. Что это значит? Это означает, что субъект может передавать данные, помимо возможности подписаться.

Определение темы (в сервисе выборки статей): let fetchSubject= new Subject<string>();

Выдача данных (передача идентификатора с боковой панели): fetchSubject.next("Eureka");

Подписка на изменения в теме: fetchSubject.subscribe((data) => { console.info("Subscriber got data >>>>> "+ data); });

Основываясь на полученном идентификаторе, вы можете сделать http-вызов. Результат можно передать субъекту, который передаст его всем подписчикам. В этом конкретном случае вам может понадобиться немного поработать над потоком.

Грубый поток, который я могу визуализировать, заключается в том, что вы можете передать результат http-вызова в теме, используя subject.next. Как только данные в субъекте будут изменены, он сообщит о новых данных везде, где вы захотите их использовать. Надеюсь, это может быть полезно для вас.

Что я хочу, так это то, что как только будет сделан http-вызов, вновь полученные данные должны быть обновлены в компоненте контента. Я могу сделать http-вызов, но не могу обновить переменную из ответа на вызов в компоненте контента. Не могли бы вы привести небольшой пример?

Viktor1903 15.07.2019 09:24

Ответ на этот вопрос был упомянут @dino. Пожалуйста, обратитесь к его коду. Я бы тоже именно так и поступил.

Ankit Joshi 15.07.2019 09:49

Взгляните на эту фотографию вашего стекблиц. Вам нужно убедиться, что подписчик получает http-запрос, и оттуда присвоить результат нужной переменной.

И как мне прослушивать новые http-запросы от компонента контента?

Viktor1903 15.07.2019 09:21

я могу сохранить stackblitz? так что я могу показать вам? Также вам нужно передать переменную this.item из компонента содержимого, если вы хотите, чтобы она обновлялась. Или сделать Наблюдателя.

CedricYao 15.07.2019 09:31

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

Viktor1903 15.07.2019 09:35

это тоже хороший ответ в качестве источника событий. Но я думаю, что в долгосрочной перспективе Subjects и Observables лучше. stackblitz.com/edit/angular-mi4zlm

CedricYao 15.07.2019 09:43

Да, я считаю, что это может быть легкий путь. Лучшим способом может быть общий сервис с субъектами.

Abishek ram R 15.07.2019 09:45

это хороший ответ от #Dino stackblitz.com/edit/angular-edotfc

CedricYao 15.07.2019 09:47

@AbishekramR Спасибо за решение. Я чувствую, что лучше использовать темы

Viktor1903 15.07.2019 10:10
Ответ принят как подходящий

Подписка на модуль HTTP означает, что как только вы получите ответ, подписка будет завершена и уничтожена по умолчанию. Поэтому ваша текущая логика никогда не сработает. Еще одна проблема, которую я видел, была здесь

updateID(id) {
    this.fetchArticlesService.fetchArticles(id)
  }

To execute the observable you have created and begin receiving notifications, you call its subscribe() method, passing an observer.

Другими словами, этот метод никогда не сработает, так как для его запуска требуется подписка на наблюдаемый объект. Подробнее об этом здесь

Решение вашей проблемы состоит в том, чтобы создать еще один наблюдаемый объект (Тема), а затем подписаться на него:

export class FetchArticlesService {
  public articles: Subject<any> = new Subject();

  constructor(
    private http: HttpClient
  ) { }

  fetchArticles(id) {
    return this.http.get('http://127.0.0.1:5000/query/' + id).pipe(
      map((result) => {
         this.articles.next(result);
      }));
  }

}

Теперь в вашем компоненте, чтобы вызвать API и загрузить только что созданный вами наблюдатель с новыми данными, вы должны сделать это:

this.fetchArticlesService.fetchArticles(id).subscribe();

А в вашем content.component.ts или любом другом компоненте вы должны подписаться на articles. Вот как вы можете автоматически «обновлять» данные ответа в нескольких местах.

this.fetchArticlesService.articles.subscribe((res) => console.info(res));

Проверьте решение здесь:https://stackblitz.com/edit/angular-edotfc

ВАЖНЫЙ: Каждый раз, когда вы «убиваете» компонент, имеющий эту подписку, также важно остановить подписку, чтобы предотвратить утечку памяти. Однако, если ваш компонент активен все время (например, панель навигации, боковая панель и компоненты этого типа), в этом нет необходимости. Лучшим способом было бы уничтожить его внутри нгондестрой

ngOnDestroy() {
  this.fetchArticlesService.articles.unsubscribe();
}

Большое спасибо! Понял в чем дело!

Viktor1903 15.07.2019 09:53

Другие вопросы по теме