Búsqueda de sitios web

typescript - Deshabilitar el envío del formulario cuando el formulario es inválido en Angular + Material


Estoy construyendo un formulario usando Angular 5.1.1/Typescript 2.4.2 + Material 5 con la biblioteca sat-popover

Intentando desactivar el botón de enviar mientras la entrada no es válida sin éxito. Estoy usando el ejemplo de validación de Material Input

la validación funciona y recibo un mensaje de error, pero el botón no está deshabilitado y el formulario se envía con un valor vacío. no puedo averiguar cómo usar la condición correcta para deshabilitar el botón mientras la entrada es inválida. he intentado

ng-disabled="!flagForm.valid"

y

ng-disabled="flagForm.$invalid"

al usar

[disabled]="!flagForm.valid"

obtengo 'TypeError: Cannot read property 'valid' of undefined'

ninguno de ellos parece funcionar. ¿qué me estoy perdiendo? aquí está el código completo.

   import { Component, Input, Optional, Host } from '@angular/core';
    import { FormControl, FormGroupDirective, NgForm, Validators} from '@angular/forms';
    import { SatPopover } from '@ncstate/sat-popover';
    import { filter } from 'rxjs/operators/filter';
    import { ErrorStateMatcher} from '@angular/material/core';

    /** Error when invalid control is dirty, touched, or submitted. */
    export class MyErrorStateMatcher implements ErrorStateMatcher {
      isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
        const isSubmitted = form && form.submitted;
        return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
      }
    } 

    @Component({
      selector: 'inline-edit',
      styleUrls: ['inline-edit.component.scss'], 
      template: `
        <form (ngSubmit)="onSubmit()" name="flagForm" novalidate>
          <div class="mat-subheading-2">Submit Your flag</div>

          <mat-form-field>
            <input matInput maxLength="140" name="flag" [(ngModel)]="flag" [formControl]="flagFormControl"
               [errorStateMatcher]="matcher">
            <mat-hint align="end">{{flag?.length || 0}}/140</mat-hint>
            <mat-error *ngIf="flagFormControl.hasError('required')">
              Flag is <strong>required</strong>
            </mat-error>        
          </mat-form-field>

          <div class="actions">
            <button mat-button type="button" color="primary" (click)="onCancel()" class="btn btn-secondary m-btn m-btn--air m-btn--custom">CANCEL</button>
            <button mat-button type="submit" ng-disabled="!flagForm.valid" color="primary" class="btn btn-accent m-btn m-btn--air m-btn--custom">Submit</button>
          </div>
        </form>
      `
    })
    export class InlineEditComponent {

      flagFormControl = new FormControl('', [
        Validators.required
      ]);

      matcher = new MyErrorStateMatcher();

      /** Overrides the flag and provides a reset value when changes are cancelled. */
      @Input()
      get value(): string { return this._value; }
      set value(x: string) {
        this.flag = this._value = x;
      }
      private _value = '';

      /** Form model for the input. */
      flag = '';

      constructor(@Optional() @Host() public popover: SatPopover) { }

      ngOnInit() {
        // subscribe to cancellations and reset form value
        if (this.popover) {
          this.popover.closed.pipe(filter(val => val == null))
            .subscribe(() => this.flag = this.value || '');
        }
      }

      onSubmit() {
        if (this.popover) {
          this.popover.close(this.flag);
        }
      }

      onCancel() {
        if (this.popover) {
          this.popover.close();
        }
      }
    }

Respuesta #1

es necesario instanciar un formulario en la clase, algo así

flagForm: FormGroup;

Respuesta #2

Por favor corrige la sintaxis para deshabilitar en Angular

 <button mat-button type="submit" [disabled]="!flagForm.valid" color="primary" class="btn btn-accent m-btn m-btn--air m-btn--custom">Submit</button>