Angular 4:在HTML页面访问表单控件

Angular 4: Access Form Controls in HTML page

我正在 Angular 4 中验证我的 HTML 表单,想通过检查表单是否 valid/invalid

来 enable/disable 一个按钮
<form novalidate #shiftForm="ngForm">
   <table>
   <thead>
      <th>Name</th>
      <th>time</th>
   </thead>
   <tbody *ngFor=let item of Items>
      <tr>
         <td>
            <div class="form-group">
               <input class="form-control" type="text" required name="shiftName"
               [(ngModel)]="item.ShiftName"#shiftName="ngModel" id="shiftName">
               <div *ngIf="shiftName.invalid && (shiftName.dirty || shiftName.touched)" class="alert alert-danger">
                  <div *ngIf="shiftName.errors.required">REQUIRED</div>
               </div>
            </div>
         </td>
         <td>
            <div class="form-group">
               <input class="form-control" type="text" required name="shiftTime"
               [(ngModel)]="item.ShiftTime" #shiftTime="ngModel" id="shiftTime">
               <div *ngIf="ShiftTime.invalid && (ShiftTime.dirty || ShiftTime.touched)" class="alert alert-danger">
                  <div *ngIf="ShiftTime.errors.required">REQUIRED</div>
               </div>
            </div>
         </td>
      </tr>
   </tbody>
   </table>
<button [disabled]="shiftForm.invalid"
(click)="updateItems()">APPLY
</button>
</form>

组件文件:

import {Component, OnInit, Inject, ViewChild, SimpleChange, SimpleChanges} from '@angular/core';
import {ElementRef, Renderer2} from '@angular/core';
import {Transition, StateService} from '@uirouter/angular';
import {ViewEncapsulation} from '@angular/core';

@Component({
    selector: 'shift-details',
    templateUrl: './shift-details.component.html',
    styleUrls: ['./shift-details.component.less'],    
    encapsulation: ViewEncapsulation.None
})

export class ShiftDetailsComponent implements OnInit {

    //variable declaration
    Items:any = [];

    constructor(
                private rd: Renderer2,                                        
                private transition: Transition,
                private $state: StateService) {
        this.$stateParams = transition.params();
    }

    ngOnInit() {
    this.Items = getShiftItems();      
    }

    getShiftItems() {
    //calling the service here to load the data in this.Items     

    }


    updateItems() {
     //calling the service here to update this.Items

     }

}

即使两个输入字段都为空并显示验证错误 shiftForm.invalid 仍然没有禁用按钮。我试过 shiftForm.form.shiftName.invalidshiftform.shiftName.invalidshiftForm.form['shiftName'].invalidshiftForm.controls['shiftName'].invalid 等。其中 None 有效。即使我直接尝试像 shiftName.invalidshiftName.errors 这样的元素名称,按钮仍然没有被禁用。

我做错了什么?我只想验证 HTML 文件中的表单,不想在打字稿文件中进行反应式表单验证。

您需要更改每个控件的 name 属性。 name 属性 必须是唯一的。

所以改变...

<input class="form-control" type="text" required name="shiftName"
       [(ngModel)]="item.ShiftName"#shiftName="ngModel" id="shiftName">

<input class="form-control" type="text" required 
       name="shiftName-{{item.ShiftName}}"
       [(ngModel)]="item.ShiftName" #shiftName="ngModel" id="shiftName">

并对 shiftTime 控件进行相同的更改。

此外,您在 *ngIf 检查 shiftTime 时有错字。应该是 shiftTime 而不是 ShiftTime.

请检查这个demo

Try this set of code. it will work

import {Component, OnInit, Inject, ViewChild, SimpleChange, SimpleChanges} from '@angular/core';
import {ElementRef, Renderer2} from '@angular/core';
import {Transition, StateService} from '@uirouter/angular';
import {ViewEncapsulation} from '@angular/core';

@Component({
    selector: 'shift-details',
    templateUrl: './shift-details.component.html',
    styleUrls: ['./shift-details.component.less'],    
    encapsulation: ViewEncapsulation.None
})

export class ShiftDetailsComponent implements OnInit {

    //variable declaration
    Items:any = [];

    constructor(
                private rd: Renderer2,                                        
                private transition: Transition,
                private $state: StateService) {
        this.$stateParams = transition.params();
    }

    ngOnInit() {
    this.Items = getShiftItems();      
    }

    getShiftItems() {
    //calling the service here to load the data in this.Items     

    }


    updateItems() {
     //calling the service here to update this.Items

     }

}
 <form novalidate #shiftForm="ngForm" (submit)="updateItems()">
    <table>
    <thead>
       <th>Name</th>
       <th>time</th>
    </thead>
    <tbody *ngFor=let item of Items>
       <tr>
          <td>
             <div class="form-group">
                <input class="form-control" type="text"  id="shiftName" name="shiftName"
                [(ngModel)]="item.ShiftName" #shiftName="ngModel" required>
                <div *ngIf="shiftName.invalid && (shiftName.dirty || shiftName.touched)" class="alert alert-danger">
                   <div *ngIf="shiftName.errors.required">REQUIRED</div>
                </div>
             </div>
          </td>
          <td>
             <div class="form-group">
                <input class="form-control" type="text" id="shiftTime" name="shiftTime"
                [(ngModel)]="item.ShiftTime" #shiftTime="ngModel" required>
                <div *ngIf="shiftTime.invalid && (shiftTime.dirty || shiftTime.touched)" class="alert alert-danger">
                   <div *ngIf="shiftTime.errors.required">REQUIRED</div>
                </div>
             </div>
          </td>
       </tr>
    </tbody>
    </table>
 <button type="submit" [disabled]="shiftForm.invalid"> APPLY </button>
</form>