Я только начинаю работать с 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
да. Когда я визуализирую его в html, значение переменной 'items' остается прежним даже после выполнения функции fetchArticles() в сервисе.
Можете ли вы предоставить код Stackblitz, где я могу воспроизвести
Я нашел два компонента: кнопку в компоненте боковой панели. И содержимое в компоненте содержимого. Если нажатие кнопки должно обновить содержимое, необходимо выполнить либо общий сервис, либо отправку идентификатора из компонента боковой панели.
Пожалуйста, проверьте мой ответ - он также имеет рабочий стек.





Вы познакомились с предметами в angular? Я думаю, что это идеальный случай для субъекта.
Субъекты сами являются наблюдаемыми, но их отличает то, что они также являются наблюдателями. Что это значит? Это означает, что субъект может передавать данные, помимо возможности подписаться.
Определение темы (в сервисе выборки статей): let fetchSubject= new Subject<string>();
Выдача данных (передача идентификатора с боковой панели): fetchSubject.next("Eureka");
Подписка на изменения в теме: fetchSubject.subscribe((data) => {
console.info("Subscriber got data >>>>> "+ data);
});
Основываясь на полученном идентификаторе, вы можете сделать http-вызов. Результат можно передать субъекту, который передаст его всем подписчикам. В этом конкретном случае вам может понадобиться немного поработать над потоком.
Грубый поток, который я могу визуализировать, заключается в том, что вы можете передать результат http-вызова в теме, используя subject.next. Как только данные в субъекте будут изменены, он сообщит о новых данных везде, где вы захотите их использовать. Надеюсь, это может быть полезно для вас.
Что я хочу, так это то, что как только будет сделан http-вызов, вновь полученные данные должны быть обновлены в компоненте контента. Я могу сделать http-вызов, но не могу обновить переменную из ответа на вызов в компоненте контента. Не могли бы вы привести небольшой пример?
Ответ на этот вопрос был упомянут @dino. Пожалуйста, обратитесь к его коду. Я бы тоже именно так и поступил.
Взгляните на эту фотографию вашего стекблиц. Вам нужно убедиться, что подписчик получает http-запрос, и оттуда присвоить результат нужной переменной.
И как мне прослушивать новые http-запросы от компонента контента?
я могу сохранить stackblitz? так что я могу показать вам? Также вам нужно передать переменную this.item из компонента содержимого, если вы хотите, чтобы она обновлялась. Или сделать Наблюдателя.
Давай, пожалуйста. Вы можете внести необходимые исправления и сохранить его.
это тоже хороший ответ в качестве источника событий. Но я думаю, что в долгосрочной перспективе Subjects и Observables лучше. stackblitz.com/edit/angular-mi4zlm
Да, я считаю, что это может быть легкий путь. Лучшим способом может быть общий сервис с субъектами.
это хороший ответ от #Dino stackblitz.com/edit/angular-edotfc
@AbishekramR Спасибо за решение. Я чувствую, что лучше использовать темы
Подписка на модуль 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();
}
Большое спасибо! Понял в чем дело!
Итак, текущая проблема? Не получается добиться?