【问题标题】:Angular7: Form validation differncesAngular 7:表单验证差异
【发布时间】:2019-09-27 11:41:14
【问题描述】:

我在检查控件的有效性时遇到了麻烦。 当我记录 完整对象 时,valid 属性是 true,而当记录 valid 仅属性 时,它会产生 false。 为什么?以及如何正确检查特定表单“控件”的有效性?

这是我的 src/app/customers/customer-edit/customer-edit.component.ts 文件中的代码:

  onDocPicked(event: Event, type: string) {
    const file = (event.target as HTMLInputElement).files[0];
    this.customerForm.get('docs').patchValue({
      [type]: file
    });
    this.customerForm.get('docs').get(type).updateValueAndValidity();
    this.customerForm.get('docs').get(type).markAsDirty();
    console.log(this.customerForm.get('docs').get(type)); // <---- HERE THE VALID PROPERTY IS TRUE (when uploading a pdf / image -- Or false when updading any other file)
    console.log(this.customerForm.get('docs').get(type).valid); // <--- AND THERE FALSE (no matter the type of file being uploaded)
  }

“挑选”的文件首先由mimeValidator 验证接受图像和pdf:

import { AbstractControl } from '@angular/forms';
import { Observable, Observer, of } from 'rxjs';

export const mimeType = (
  control: AbstractControl
): Promise<{ [key: string]: any }> | Observable<{ [key: string]: any }> => {
  if (!control.value || typeof(control.value) === 'string') {  return of(null); }
  const file = control.value as File;
  const fileReader = new FileReader();
  const frObs = Observable.create(
    (observer: Observer<{ [key: string]: any }>) => {
      fileReader.addEventListener('loadend', () => {
        const arr = new Uint8Array(fileReader.result as ArrayBuffer ).subarray(0, 4);
        let header = '';
        let isValid = false;
        for (let i = 0; i < arr.length; i++) {
          header += arr[i].toString(16);
        }
        switch (header) {
          case '89504e47':
            isValid = true;
            break;
          case 'ffd8ffe0':
          case 'ffd8ffe1':
          case 'ffd8ffe2':
          case 'ffd8ffe3':
          case 'ffd8ffe8':
            isValid = true;
            break;
          case '25504446':
            isValid = true;
            break;
          default:
            isValid = false; // Or you can use the blob.type as fallback
            break;
        }
        if (isValid) {
          observer.next(null);
        } else {
          observer.next({ invalidMimeType: true });
        }
        observer.complete();
      });
      fileReader.readAsArrayBuffer(file);
    }
  );
  return frObs;
};

这是我的项目的堆栈闪电:https://stackblitz.com/github/ardzii/test

【问题讨论】:

    标签: angular forms validation upload


    【解决方案1】:

    那么为什么控制台日志会有所不同呢?我们可以首先说角度形式实际上是异步的,所以这是答案的一部分。其次,我们必须知道控制台日志是如何工作的。如here所述:

    当您在控制台中手动展开对象时获取对象的状态 - 而不是在记录时。

    所以valid 状态已经设置好了。由于表单是异步的,有时我们需要稍微超时才能获得最新的值,所以这样做:

    setTimeout(() => {
      console.log(this.customerForm.get('docs').get(type).valid);
    },100);
    

    将打印true

    DEMO

    【讨论】:

    • 明白。那么如何在我的表单上异步链接一些命令呢?我的目标很简单:如果 mime 类型不正确,则创建警报并重置表单的相应部分......有没有办法在 updateValueAndValidity() 命令上创建承诺并将其余部分链接起来?
    猜你喜欢
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 2019-12-10
    • 2020-04-03
    • 2018-02-08
    相关资源
    最近更新 更多