【问题标题】:Angular - How to return a bool from a Subscription in my service-component?Angular - 如何从我的服务组件中的订阅返回布尔值?
【发布时间】:2020-04-24 06:09:50
【问题描述】:

我有一个 login.service.ts 和我的 login.component.ts

在我的登录组件中,我有一个输入字段,用户在其中输入用户名,当他点击“登录”时,我们检查是否 用户名在此调用中有效:

<button color="primary" mat-raised-button (click)="loadUserInfo(email.value)">
      continue
      <mat-icon>arrow_forward</mat-icon>
    </button>

loadUserInfo(userLogin: string) {
this.loginService.processLogin(userLogin);
}

调用我的服务:

processLogin(loginId: string) {
return this.http.get("api/" + loginId).subscribe(
(user: User) => {

        this.userSub.next(user);
      },
      err => {
        console.error("Username not valid");
      }
    );
  }

我无法理解以下内容: 如果呼叫不成功,并且没有具有该用户名的用户,我如何在我的login.component.ts 中显示错误消息 输入字段?我需要一个 bool 或其他东西,但错误处理在 service component 中,所以不太确定最好的方法是什么

我会在我的输入字段下放这个:

  <div *ngIf="userNotValid"> Error, this user doesn't exist</div>

但是处理这种情况的最佳方法应该是什么?用户按下按钮,API 返回错误,现在,如何在 login-component html 文件中显示错误? 谢谢

【问题讨论】:

  • 您必须使用BehaviorSubject 来存储状态。并使用async 管道在您的模板中检索它。
  • 我的第一个想法是在组件本身做订阅,直接改变subscribe中userNotValid的状态。
  • @Ploppy 你能举个例子吗?谢谢
  • @tenkmilan 遗憾的是,逻辑必须保留在服务中!否则我会那样做
  • @AJ989 晚上关机,但如果你早上没有答案,我会给你打一个!

标签: angular subscription


【解决方案1】:

BehaviorSubject 用于存储变量。它就像Observable 一样工作,但您可以随时访问其最新值。

async 管道用于呈现来自异步源的值,例如 Observable 或 BehaviorSubject 或 Subject。

注意:Subject 与 BehaviorSubject 不同,不存储最新值。

服务

public error$ = new BehaviorSubject(false);

....

this.error.next(true); // to trigger a new error

组件

<div *ngIf="service.error$ | async">Error<div>

【讨论】:

  • 我也在听从用户的建议后回答了我的问题,我的解决方案是否与您的解决方案基本相同,只是没有新的 BehaviorSubject ?现在我把它变成了一个可观察的,所以我可以使用返回来显示错误?
  • 我认为由你决定你喜欢哪一个?
【解决方案2】:

正如许多人建议的那样,我应该在我的服务中使其成为可观察的,并从我的组件中订阅它,我不想这样做,因为我还需要更改其他内容,但如果这是最干净的方式我只是可能会这样做。

这样做有意义吗,所以它都返回一个布尔值,如果用户有效,它将触发 next() 到我的 behaviourSubject 存储当前用户?

processLogin(loginId: string): Observable<boolean> {
    return this.http.get("api/" + loginId).pipe(map(
      (info: UserInfo) => {
        console.log("userinfo:", info);
        return info;
      }),
      catchError(err => of(null as UserInfo))
    ).pipe(tap(
      uInfo => {
        this.userSub.next(uInfo);
      }
    ),
    map(u => u != null)
    );
  }

我这样做正确吗?或者我可以改进它吗? 在我看来,现在我有两个我想要的东西,一个布尔值作为返回值,如果是现有用户,它将next() 值。

【讨论】:

  • 我更喜欢使用响应式表单模块进行表单验证。
  • 不确定我是否理解,对于验证我也更喜欢,但它需要一个异步验证器,对吗?只需一个输入?保留代码已经存在并改用它不值得吗?
  • 整个应用程序中只有一个输入吗?如果您在整个应用程序中不使用任何输入字段,那么 ReactiveFormModule 将成为 common.js 的一部分,并将在第一个实例中加载。其次,我更喜欢创建自定义输入组件,它支持所有验证并处理组件内的错误消息,并进一步添加对使用内容投影的输入元素内的前缀或后缀等附加功能的支持。这将帮助您实现松散耦合,并且将来任何类型的需求更改都需要进行一次更改
猜你喜欢
  • 2019-03-06
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
相关资源
最近更新 更多