角度:身份验证失败时如何停止微调器加载?

问题描述 投票:0回答:1

我需要我的代码的帮助。我是新手,我对ngrx的效果有疑问。因此,在我的身份验证服务中,我声明了登录失败,该登录类型是可观察的,我希望当身份验证失败登录时,微调框停止旋转并再次输入数据。我应该在ngrx / effect中添加什么部分?

SERVICE COMPONENT

 public loginFailed: Observable<boolean>;

NGRX / EFFECTS

 @Effect()
 public login$: Observable<any> = 
  this.actions$.pipe(
  ofType(AuthActionTypes.LoginAction),
  mergeMap((action: Login) => 
  this.authService.login(action.payload).
  pipe(
  map((user: User) => {

    if(user.username != null && user.password != null) {
      this.authService.loginFailed
    }

    return {
      type: AuthActionTypes.LoginSuccessAction,
      payload: user
    }
  }),
  catchError(() => {
    return of({

    });
  })
))

HTML

 <div fxLayoutAlign="center center" class="button">
    <button class="btn-login" type="button" color="primary" [disabled]="isLoginBtnDisabled" (click)="onSubmit()"
        mat-button>
   <mat-icon *ngIf="isLoginBtnDisabled; else loginText">
    <mat-spinner diameter="20"></mat-spinner>
  </mat-icon>
  <ng-template #loginText>Login</ng-template>
</button>

angular ngrx-effects
1个回答
0
投票

嗯,有很多方法。我会说以下。这里有2个州。一种是authentication状态,一种是loading状态。

您应该有2个减速器,其中一个处理loading状态,另一个处理authentication部分。

通常取决于UX设计,您希望微调器在每次请求完成时都显示为叠加,而与您所在的页面/组件无关。

实现此目的的一种方法是,通过创建一个用于创建此叠加层的LoadingService,与该loadState一起使用的loadingService(该示例使用来自Angular Material的CDK叠加层完成)。

@Injectable()
export class LoadingService {

  private overlayRef: OverlayRef;
  private currentCount = 0;

  constructor(private overlay: Overlay, private store: Store<ApplicationState>) {
    this.store.pipe(
      select(fromLoading.loadingState)
    ).subscribe(loadingState => {
        if (loadingState.count > this.currentCount) {
          if (this.currentCount === 0) {
            this.overlayRef = this.cdkOverlayCreate();
            this.overlayRef.attach(new ComponentPortal(MatSpinner));
          }
        } else if (loadingState.count === 0 && this.currentCount !== 0) {
          this.overlayRef.dispose();
        }
        this.currentCount = loadingState.count;
      }
    );
  }

  cdkOverlayCreate(): OverlayRef {
    return this.overlay.create(
      {
        hasBackdrop: true,
        backdropClass: 'dark-backdrop',
        positionStrategy: this.overlay.position()
          .global()
          .centerHorizontally()
          .centerVertically()
      }
    );
  }
}

正如我之前说过的,您希望加载项独立于所处的组件而显示。这意味着状态的操作应从HTTP拦截器完成。它可能看起来像这样。

@Injectable()
export class LoadingInterceptor implements HttpInterceptor {
  constructor(private store: Store<ApplicationState>) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.store.dispatch(new fromLoading.IncrementLoadingAction());
    return next.handle(req).pipe(
      finalize(() => this.store.dispatch(new fromLoading.DecrementLoadingAction())));
  }
}

每次完成请求时,加载状态都会增加,而当请求完成(失败或失败)时,状态会减少。正在加载服务会订阅此状态,并通过显示/隐藏/保留叠加层来对更改做出反应。

一旦完成,每次完成请求(包括身份验证)时,就会出现加载。

对于您的示例,应该在效果内分派一个在执行请求时显示加载的动作,并分派一个在成功错误情况(catchError()= > {...})。您可以从一个效果返回多个动作

return [{
      type: AuthActionTypes.LoginSuccessAction,
      payload: user
    }, {
      type: LoginActionTypes.DecrementLoading,
    }]

并且您还应该在执行auth请求之前分派增加负载的操作。

this.store.dispatch(new LoadingIncrementAction())
this.authService.login(action.payload).
© www.soinside.com 2019 - 2024. All rights reserved.