#angular #service #constructor #synchronized #angular-http-interceptors
#angular #Обслуживание #конструктор #синхронизировано #angular-http-перехватчики
Вопрос:
Я пытаюсь использовать следующую службу Angular 10
, то есть службу, которая ищет выполняемые http-запросы, эта служба меняется с true на false, если есть http-запросы, это нормально, я проверяю это с помощью журнала консоли
export class SpinnerService implements HttpInterceptor {
public loading: boolean = false;
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loading = true;
// console.log('estado spinner: >> ', this.loading);
return next.handle(req).pipe(
finalize(() => {
this.loading = false;
// console.log('todas solicitudes ok');
console.log('estado espinner: >>', this.loading);
})
);
}
}
Когда я пытаюсь использовать службу в другом компоненте, у меня возникают проблемы, потому что служба не синхронизирована с локальной переменной компонента.
Например, переменная загрузки сервиса начинается с false, затем она становится true, затем становится false, и все это за период времени в 5 секунд, который требуется остальной части API для передачи данных.
Переменная загрузки изначально синхронизируется с переменной загрузки как false, но затем она не соответствует состояниям переменной загрузки, переменная загрузки остается false
Как мне синхронизировать эти переменные? помогите, пожалуйста, я не знаю, как искать
Это конструктор, в котором я вызываю службу из переменной загрузки,
public carga = this._spinnerService.loading;
constructor(private _spinnerService: SpinnerService)
{
this.crearFormulario(); // inicializar formulario
// this._spinnerService.loading = this.spinneres;
// console.log('estado inicial spinner: >>', this._spinnerService.loading);
console.log('estado inicial spinner: >>', this.carga);
}
Комментарии:
1. Ok значение устанавливается в true только внутри функции перехвата. Затем ему присваивается значение false, как только возвращается любой http-запрос. Вопрос в том, сколько запросов он обрабатывает и какова разница во времени? Скорее всего, это происходит так быстро, что истинное значение никогда не отображается, за исключением, возможно, 50 мс или меньше. Yo creo que
2. это может быть связано с тем, как вы могли ограничить область действия своего сервиса. Ваша служба будет перехватывать все сетевые запросы и применять логику, которую вы ввели. Так, например, если у вас есть 2 вызова API, при выполнении первого перехватчик устанавливает значение true, а затем в finalize он устанавливает его в false, то же самое произойдет и со вторым запросом. Таким образом, вы не можете гарантировать, что this.loading будет вести себя так, как вы ожидаете.
3. какова область действия этого SpinnerService, может быть, предоставить его на уровне компонента, а не модуля. так что он создает экземпляр самого себя для каждого компонента, тем самым прикрепляя переменную загрузки к компоненту. это связано с внедрением зависимостей
Ответ №1:
Я думаю, что то, что вы пытаетесь показать, — это счетчик при каждом вызове сети http, выполняемом из вашего приложения. Если это так, вы почти правы, за исключением общедоступной переменной ‘loading’, которую вы упомянули в классе SpinnerService.
import { NgxSpinnerService } from 'ngx-spinner';
export class SpinnerService implements HttpInterceptor{
constructor(private spinner: NgxSpinnerService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
this.spinner.show();
return next.handle(req).pipe(
finalize(() => {
this.spinner.hide();
}
)
);
}
}
Пожалуйста, установите
npm i ngx-spinner
в вашем app.component.ts
<ngx-spinner></ngx-spinner>
Пожалуйста, обратитесь:
Комментарии:
1. muchas gracias por contestas, se puede hacer de esa manera, pero no me gustan muchas las dependencias ngx
Ответ №2:
Я смог решить проблему, я создал классы в том же файле ts, чтобы он был более упорядоченным, один класс отвечает за перехват логики, а другой класс отвечает за прослушивание http-запросов, я проверил много решений, но это было то, которое мне больше всего понравилось, потому чтоон возвращает true или false в html без необходимости использования зависимостей.
это ts-файл используемой вами службы, вам просто нужно импортировать службу в компонент, который вы хотите использовать spinners.
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse, HttpErrorResponse } from '@angular/common/http';//para interceptor de http
import { BehaviorSubject, Observable } from 'rxjs';//para interceptor de http
import { tap } from 'rxjs/operators';//para interceptor de http
@Injectable({
providedIn: 'root'
})
//servicio interceptor que escucha si hay solicitudes http en progreso
export class interceptHttpService implements HttpInterceptor{
constructor(private _pruebaspinerss3 : spinnerService ) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
this._pruebaspinerss3.requestStarted();
return this.handler(next,request);
}
handler(next ,request)
{
return next.handle(request)
.pipe(
tap(
(event) =>{
if (event instanceof HttpResponse){
this._pruebaspinerss3.requestEnded();
}
},
(error: HttpErrorResponse) =>{
this._pruebaspinerss3.resetSpinner();
throw error;
}
),
)
};
}
export class spinnerService{
private count = 0;
private spinner$ = new BehaviorSubject<string>('');
getSpinnerObserver(): Observable<string>{
return this.spinner$.asObservable();
}
requestStarted() {
console.log('spinner activado');
if ( this.count === 1) {
this.spinner$.next('start');
}
}
requestEnded() {
console.log('spinner desactivado');
if (this.count === 0 || --this.count === 0) {
this.spinner$.next('stop');
}
}
resetSpinner() {
console.log('error en solicitud, reset spinner');
this.count = 0;
this.spinner$.next('stop');
}
}
в файле app.module ts
import { interceptHttpService, spinnerService } from './services/spinner.service';