无法验证角形式

时间:2021-03-01 20:49:07

标签: angular typescript forms validation reactive

我正在创建一个需要测试连接的 Angular 应用程序。但是,连接可以在字段留空的情况下保存。我无法成功地将 Angular 验证器与响应式表单集成。

将验证器添加到此 html 代码以防止它被提交为空白的最佳方法是什么?我已经用 ngIf 代码更新了 HTML,但它抛出了我在底部包含的错误。

这里是 HTML

<div class="cm-content-blocks">
    <ol class="breadcrumb">
               <li><a routerLink="/"><i class="fa fa-home"></i>Home</a></li>
               <li><a routerLink="/data-sources"><i class="fa fa-database mr-1"></i>Data Sources</a></li>
               <li><a routerLink="/selectdatabase"><i class="fa fa-sitemap mr-1"></i>Configure Data Source</a></li>

               <li  class="active"><i class="fa fa-spinner mr-1"></i>Test Connection</li>  
           </ol>
  </div>
<div class="clearafter headbtnc">
    <h3 class="headc mt-4">
    Test Connection:
    <!-- <div class="subhead">Create new database connection </div> -->
    </h3>
</div>

<section class="menublock">
    


<!-- test connection form -->
    <form [formGroup]="dataSourceCredentials" (ngSubmit)="postConnection()">
        <div class="form-group">
        <input formControlName="id" type="hidden" class="form-control">
        </div>
        <section class="inputc" >
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Database Type:</label>
                <select class="form-control" formControlName="databaseType" >
                    <option value="mysql" selected>MySQL</option>
                </select>
            </aside>
        </section>
        <section class="inputc" >
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Connection Name:</label>
                <input class="input-field" formControlName="name" type="text"   name="name" placeholder="Connection Name" required>
            </aside>    
            
           <!--ngIf code-->
            <!--*ngIf="driver.invalid && (driver.dirty || driver.touched)" class="alert alert-danger"-->
            <!--*ngIf="driver.errors.required"-->

            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Driver:</label>
                <input class="input-field" formControlName="driver" type="text"   name="driver" placeholder="Driver" required>
                <div *ngIf="!dataSourceCredentials.get('driver').valid &&  dataSourceCredentials.get('driver').touched" class="alert alert-danger">
                    <div>
                        Driver is required
                    </div>
                </div>      
            </aside>    
        </section>
    

        <section class="inputc" >
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Host Name:</label>
                <input class="input-field" formControlName="hostName" type="text" placeholder="Host Name (Eg: 40.102.118.70)" >
                <div class="alert alert-danger">
                    <div>
                        Host Name is required
                    </div>
                </div>
            </aside>
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Port:</label>
                <input class="input-field" formControlName="port" type="text" placeholder="Port" >             
                <div class="alert alert-danger">
                    <div>
                        Port is required
                    </div>
                </div>
            </aside>
        </section>

        <section class="inputc">
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Username:</label>
                <input class="input-field" formControlName="username" type="text" placeholder="Username" required>
                <div class="alert alert-danger">
                    <div>
                        Username is required
                    </div>
                </div>
            </aside>

            <aside class="col-md-6 fieldc">
                <div class="input-group mb-3">
                    <label for="" class="inputlabel">Password:</label>
                    <input type="text" class="form-control input-field"  formControlName="password" type="password" [type]="hide ? 'password':'text'" placeholder="Password">
                    <div class="input-group-append">
                      <span class="input-group-text bg-light" id="basic-addon2">    
                          <i class="{{hide?'fa fa-eye-slash':'fa fa-eye'}}" (click)="hide = !hide"></i>
                      </span>
                    </div>
                  </div>
                  <div class="alert alert-danger">
                      <div>
                        Password is required
                      </div>
                  </div>
            </aside>
        </section>

        <!-- Saved connections -->

        <section class="inputc" >
            <aside class="col-md-6 fieldc" >
                <h4 cllass="innrcaption">Or select from your saved connections:</h4>
                <mat-form-field appearance="fill">
                <mat-label>Select from previous connections</mat-label>
                <mat-select>
                    <mat-option class="mr-4" *ngFor="let item of rdbmsConnectorList" [value]="item.databaseType" (click)="populateForm(item)">
                    {{item.name}}   
                    </mat-option>
                    <!-- <a href=""><i class="fa fa-trash" (click)="deleteSavedConnection(item.id)"></i></a> -->  
                </mat-select>  
                </mat-form-field>
            </aside>
        </section>
                
        
            
        <div class="graybdrt fifteen_pt fifteen_pb clearafter">
            <button class="tertiary-active fr" click="submit">
                <span>Save connection</span>
                <i class="fa fa-arrow-right fiveml" aria-hidden="true"></i>
            </button>
            <button class="tertiary-active fr" type="button" (click)="testConnection()">
                <span class="mr-2">Test connection</span>
                <i class="fa fa-spinner" aria-hidden="true"></i>
            </button>  
            <button class="tertiary-active fr float-left" type="button" (click)="clearForm(dataSourceCredentials)">Clear</button>      
        </div>

        
    <!-- <button (click)="loadData()" class="btn btn-danger btn-block " type="button">Load Data</button> -->
        
    </form>

</section>

TS

import { Component, OnInit, Input, NgModule } from '@angular/core';
import { FormControl, NgForm, FormGroup, FormBuilder, Validators, FormArray } from '@angular/forms';
import { Config } from '../../../config'
import { DataSourceControllerService } from '../../../services/api/data-source-controller.service'
import { Router } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { MatSnackBar, MatSnackBarConfig, MatSnackBarHorizontalPosition, MatSnackBarVerticalPosition, } from '@angular/material/snack-bar';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';

import { RdbmsConnector } from "../../../models/rdbms-connector.model"
@Component({
  selector: 'app-create-and-test-connection',
  templateUrl: './create-and-test-connection.component.html',
  styleUrls: ['./create-and-test-connection.component.scss']
})
export class CreateAndTestConnectionComponent implements OnInit {

  //test connection object
  data: any;

  //post connection object
  connection: any;

  rdbmsConnectorList: RdbmsConnector[];
  hide = true;
  //snackbar 
  horizontalPosition: MatSnackBarHorizontalPosition = 'start';
  verticalPosition: MatSnackBarVerticalPosition = 'bottom';
  status: string;

  //validator
  connectionForm: FormGroup;

  form = {driver:''};


  constructor(private formBuilder: FormBuilder, public service: DataSourceControllerService, public router: Router,
    private snackBar: MatSnackBar
  ) {


  }

  //form model

  dataSourceCredentials = this.formBuilder.group({
    id: [""],
    databaseType: ["", Validators.required],
    driver: ["", Validators.required],
    hostName: ["", Validators.required],
    port: ["", Validators.required],
    username: ["", Validators.required],
    password: ["", Validators.required],


  })






  getAllConnections() {
    this.service.getRDBMSConnectors().toPromise()
      .then(response => this.rdbmsConnectorList = response as RdbmsConnector[]
      )
  }

  //populate form with saved connection

  populateForm(savedRecord: RdbmsConnector) {

    this.dataSourceCredentials.setValue({
      id: savedRecord.id,
      databaseType: savedRecord.databaseType,
      driver: savedRecord.driver,
      hostName: savedRecord.hostName,
      port: savedRecord.port,
      username: savedRecord.username,
      password: savedRecord.password,
    })


  }

  //populate form with saved connection

  clearForm(recordToBeCleared: any) {

    this.dataSourceCredentials.setValue({
      id: "",
      databaseType: "",
      driver: "",
      hostName: "",
      port: "",
      username: "",
      password: "",
    })


  }

  // post connection method
  postConnection() {
    if (this.dataSourceCredentials.value.id == "") {

      this.service.postRDBMSConnector(this.dataSourceCredentials.value).subscribe((response) => {
        console.log(response)
        this.connection = response;
        this.router.navigateByUrl(`/configureingestion/${this.connection.id}`);
        this.openSnackBar("New Connection created", '?')
      });

    } else {
      this.openSnackBar("Connection already exists", '❗')

    }
  }

  // test connectio nmethod

  testConnection() {
    this.service.testRDBMSConnector(this.dataSourceCredentials.value).subscribe((response) => {
      this.data = response;
      console.log(response)
      if (this.data.status.toLowerCase() == "connection successful") {
        console.log(this.data.status)
        this.openSnackBar(this.data.status, '?')
      } else {
        this.openSnackBar(this.data.status, '❌')

      }





    });

  }

  //snackbar
  openSnackBar(status: string, statusLogo: string) {
    this.snackBar.open(status, statusLogo, {
      duration: 3000,
      horizontalPosition: this.horizontalPosition,
      verticalPosition: this.verticalPosition,
      panelClass: ['tertiary-active']

    });
  }


  ngOnInit(): void {
    this.getAllConnections();

    this.connectionForm = new FormGroup ({
      driver: new FormControl(this.form.driver, [
        Validators.required
      ])
    })
  }

  get driver() {return this.connectionForm.get('driver');}

}

错误代码

Error: src/app/components/connections/create-and-test-connection/create-and-test-connection.component.html:47:112 - error TS2531: Object is possibly 'null'.

47                 <div *ngIf="!dataSourceCredentials.get('driver').valid &&  dataSourceCredentials.get('driver').touched" class="alert alert-danger">

1 个答案:

答案 0 :(得分:0)

像这样使用 ngIf 条件,

<div *ngIf="!dataSourceCredentials.get('type').valid &&  dataSourceCredentials.get('type').touched" class="alert alert-danger">
相关问题