【问题标题】:How to create validation for autosave reactive Angular 2 form.如何为自动保存响应式 Angular 2 表单创建验证。
【发布时间】:2017-02-27 05:15:27
【问题描述】:

我需要有关如何创建自动保存响应式 Angular 2 表单的建议。基本上用户输入值,如果值被验证,表单会自动保存。这是代码

    export class BusinessFoundationsPage {

      businessFoundationsForm: FormGroup;
      userId: string;
      YouTuber: YouTuber;
      loading: any;
      isThisFirstTimeFlag: boolean;
      businessFoundationsKey: string;
      locationId: string;

      constructor(public af: AngularFire, public navCtrl: NavController, public navParams: NavParams, public fb: FormBuilder, private loadingCtrl: LoadingController, public userData: UserData) {
        this.locationId = this.navParams.get('locationId');
        this.loading = this.loadingCtrl.create({
          content: 'Please wait...'
        });

        this.loading.present();

        this.businessFoundationsForm = this.fb.group({
          businessFoundationsQ1: ['', [Validators.required, Validators.minLength(10)]],
          businessFoundationsQ2: ['', [Validators.required, Validators.minLength(10)]]
        })

      }

      ionViewDidLoad() {
        console.log('ionViewDidLoad BusinessFoundationsPage');

        this.af.auth.subscribe(auth => {
          if (auth) {
            console.log ("Current State: Login");
            this.userId = auth.uid;
            this.userData.getUserDetail(this.userId).subscribe(user => {
              this.YouTuber = user;

              let formControls: any = this.businessFoundationsForm.controls;
              if (this.YouTuber.businessFoundations) {
                this.isThisFirstTimeFlag = false;
                this.userData.getBusinessFoundationsData(this.YouTuber.businessFoundations).subscribe(data => {
                  this.businessFoundationsKey = data.$key;
                  formControls.businessFoundationsQ1.setValue(data.businessFoundationsQ1);
                  formControls.businessFoundationsQ2.setValue(data.businessFoundationsQ2);
                  this.loading.dismiss();
                })
              } else {
                this.isThisFirstTimeFlag = true;
                this.loading.dismiss();
              }
            });

          } else {
            this.loading.dismiss();
            console.log ("Current State: NOT Login");
          }
        });

      }

      saveForm(): void {
        let data = this.businessFoundationsForm.value;
        let dataToSave = {
          locationId: this.locationId,
          uid: this.userId,
          youTuberName: this.YouTuber.name,
          businessFoundationsQ1: data.businessFoundationsQ1,
          businessFoundationsQ2: data.businessFoundationsQ2,
        }
        console.log (data);
        if (this.isThisFirstTimeFlag) {
          this.userData.createBusinessFoundationsData(this.userId, dataToSave);
        } else {
          this.userData.updateBusinessFoundationsData(this.businessFoundationsKey, dataToSave);
        }
      }

    }

3 个输入字段有 Validators.required、Validators.minLength(10)。这是 HTML:

    <form [formGroup]="businessFoundationsForm" (change)="saveForm()">
  <ion-item text-wrap>
    <ion-label floating>What additional revenue streams have the most growth potential for your channel?</ion-label>
    <ion-textarea fz-elastic formControlName="businessFoundationsQ1"></ion-textarea>
  </ion-item>
  <ion-item text-wrap>
    <ion-label floating>What is one business challenge you have and what can you do to improve in this area?</ion-label>
    <ion-textarea fz-elastic formControlName="businessFoundationsQ2"></ion-textarea>
  </ion-item>
</form>

每次通过点击我的 Firebase 服务器更改输入时都会保存该表单。但我希望它仅在验证其中一个字段时保存。另外,如果字段值相同,我也不想调用 Firebase(保存操作)。基本上,我需要在绝对必要时最小化调用该操作的数据库,而无需用户单击愚蠢的提交按钮。我在离子 2 顺便说一句。所以假设情况可以是:

  1. 首先输入了输入字段,但不符合验证 - saveForm 停止。
  2. 第一个输入字段已输入,并通过验证,但第二个字段仍为空 - saveForm 保存(自动保存!!)
  3. 输入字段 second 已键入,但不符合验证且字段 first 未更改 - saveForm 停止。
  4. 输入字段 second 已键入,并符合验证,但字段 first 为空 - 仍然 saveForm 保存(自动保存!!)
  5. 用户第一个编辑字段但不符合验证,第二个字段没有更改 - saveForm 停止。

我想不出其他情况。关于如何使用反应/可观察反应形式构建它的任何建议?

【问题讨论】:

    标签: angular ionic2 angular2-forms reactive-forms


    【解决方案1】:

    订阅 200 毫秒 debounce 或更长时间的值更改,因此如果用户在 200 毫秒内没有输入,则将调用 subscribe。如果表单有效,请保存

    constructor(public af: AngularFire, public navCtrl: NavController, public navParams: NavParams, public fb: FormBuilder, private loadingCtrl: LoadingController, public userData: UserData) {
        this.locationId = this.navParams.get('locationId');
        this.loading = this.loadingCtrl.create({
            content: 'Please wait...'
        });
    
        this.loading.present();
    
        this.businessFoundationsForm = this.fb.group({
            businessFoundationsQ1: ['', [Validators.required, Validators.minLength(10)]],
            businessFoundationsQ2: ['', [Validators.required, Validators.minLength(10)]]
        })
    
        this.businessFoundationsForm.valueChanges
            .debounceTime(200)
            .subscribe(() => {
                if (businessFoundationsForm.valid && businessFoundationsForm.dirty) {
                    this.saveForm();
                    businessFoundationsForm.reset()
                }
            });
    
    }
    

    【讨论】:

    • 您好,感谢您的快速回复。你能解释一下什么是 autoSaveSubscriber 以及为什么是 autoSaveSubscriber.unsubscribe() 吗?另外,您是否建议我不要在模板表单级别使用 (change)="saveForm()" ,而是将 valueChanges 放在构造函数中并立即初始化?
    • 实际上,您的解决方案比我原来的问题解决方案更多地调用了我的数据库。即使值与 debounceTime 内的原始值完全相同,它也会调用数据库 - 我将其设置为 1000。当表单首次从空值初始化以从 Firebase 加载先前的值时,它也会调用数据库。此外,它每隔 debounceTime 间隔调用数据库 - 与使用 Ionic 之前一样,它仅在输入不再突出显示时调用(用户完成输入并关闭手机上的键盘)。因此,不幸的是,这不是一个更好的解决方案。
    • @HughHou 嘿,autosaveSubscruber 是未清理的代码,当我开始时我有一个想法,但后来做得更好。检查我在表单中的更新,有一个 touch 属性,该属性表示用户是否修改了 smth
    • @HughHou 我还添加了重置表单以防止保存已保存的数据
    • @HughHou 现在检查,它只是有效的属性angular.io/docs/ts/latest/api/forms/index/…
    猜你喜欢
    • 2019-07-28
    • 2017-03-26
    • 2017-08-28
    • 2022-01-23
    • 2017-04-30
    • 2017-04-12
    • 2019-06-28
    • 2017-09-09
    • 2019-03-12
    相关资源
    最近更新 更多