【问题标题】:How to check Observable if data exist in Angular 8如果Angular 8中存在数据,如何检查Observable
【发布时间】:2019-11-24 14:27:43
【问题描述】:

我正在尝试以反应式编程方式实现 CRUD 功能。我有一个表单,其中一个字段 identifier_name 必须是唯一的。

但是,在调用 create new 或 update 方法之前,我需要先检查我正在创建或更新的 identifier_name 字段的值是否已经存在于我的 observable 是这样的 observable 中。

this.userService.users$;

以下是我的组件中的代码。

@Component({...})
    export class UserEditComponent implements OnInit, OnDestroy {

        subscription: Subscription = new Subscription();

        ngOnDestroy() {
          this.subscription.unsubscribe();
        }

        saveUser(): void {
            if (this.userForm.valid) {
                this.identifierExists$.subscribe(exists => {
                      if (exists) {
                        this.snackBar.open('The scope identifier must be unique.', 'Close', { duration: 5000 });
                      } else {
                        if (this.isNewRecord) {
                            this.createNewUser();
                        } else {
                            this.updateUser();
                        }
                      }
                    })          
            } else {
                this.snackBar.open("An error occured while saving your changes. Please try again.", "Close", { duration: 5000 });
            }
        }

      createNewUser(): void {
        this.subscription.add(
          this.userService.saveUser(this.userForm.value)
            .pipe(catchError(this.handleError))
            .subscribe(() => {
              this.snackBar.open('New user successfully created.', 'Close', { duration: 5000 });
            })
        )
      }

      updateUser(): void {
        this.subscription.add(
          this.userService.selectedUserIdAction$
            .pipe(
              switchMap(id => this.userService.updateUser(id, this.userForm.value))
            )
            .subscribe(_ => {
              this.snackBar.open("User successfully updated.", "Close", { duration: 5000 })
            })
        )
      }

    }

我的想法是这样做。

    private identifierSubject = new BehaviorSubject<string>('');
    identifierAction$ = this.identifierSubject.asObservable();

    identifierExists$ = this.identifierAction$.pipe(
            switchMap(identifier => {
                this.userService.users$
                    .pipe(
                        map(users => users.some(user => user.identifier_name === identifier))
                    )
            })
        )

我不确定这是否是满足我要求的正确方法,因为我对反应式编程的概念还很陌生。

另外,如果你注意到我的两种方法createNewUser() 和updateUser。有没有一种方法可以触发 create 和 update 而无需订阅?我在反应式编程中所知道的是避免subscribe。但是,不确定如何以正确的方式做到这一点。

希望您能指导我如何以反应式编程方式正确地做到这一点。

TIA

【问题讨论】:

    标签: angular reactive-programming angular-reactive-forms rxjs6


    【解决方案1】:
    1. 您说您有一个表单并且您希望一个值是唯一的。我强烈建议您在按下 saveUser() 时不要进行此检查。而是使用验证器,因此在您拥有唯一名称之前,表单将无效。反应式表单同时提供 - 同步和异步 - 验证器。
    2. 您是否知道,每次提交点击都会为您的组件添加订阅?
    3. 我很难理解为什么您的标识符存储在 BehaviorSubject 中。是不是太过分了?

    关于您的创建+更新,请查看此帖子:Angular http.post without .subscribe callback

    【讨论】:

    • 嘿@MoxxiManagarm。谢谢你的评论。我会试一试#1 sugestion。对于#2,是的,我知道我正在为创建和更新方法添加订阅,以便我取消订阅onDestroy。我更新了我的帖子以包含此内容。对于#3,我正在使用BehaviorSubject 观察identifier_name 的值,因此我可以使用switchMap 将其搜索到我的用户列表中。我知道这可能很丑陋而且不常见,但我很高兴有更好的建议。干杯!
    • 这里只是更新。我已经实现了自定义验证器并且它可以工作。但是,下一个挑战是,我需要 identifier_name 的旧值进行一些额外检查,例如,如果当前选择的 identifier_name 等于控件的新值,那么我不应该将其标记为现有记录.
    猜你喜欢
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    • 2017-04-24
    • 2012-03-23
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多