无法使用angular设置字段的动态验证

Mad*_*pop 8 typescript angular

我正面临现有应用程序的问题,下面是我的场景我有以下JSON格式

.html代码

<div class="panel-group" id="accordion">
    <div *ngFor="let property of Tree.properties">
      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title">
            <a class="link" data-toggle="collapse" data-parent="#accordion" href="#dataCatg-{{property.name}}">
              <div *ngIf="property.required">
                <span class="glyphicon glyphicon-chevron-right"></span>{{property.name}}
              </div>
              <div *ngIf="!property.required">
                <span class="glyphicon glyphicon-chevron-right"></span>{{property.name}}
              </div>
            </a>
          </h4>
        </div>
        <div id="dataCatg-{{property.name}}" class="panel-collapse collapse">
          <div class="panel-body">
            <ul class="list-group">
              <li class="list-group-item" *ngFor="let prop of property.details">
                <div *ngIf="prop.details.visible">
                  <div class="row">
                    <div class="col-md-4">
                      <div *ngIf="data.includes(prop.name)">
                        <label class="inline-label" for="{{prop.name}}">{{prop.name}}</label>
                      </div>
                      <div *ngIf="!data.includes(prop.name) ">
                        <label class="inline-label " for="{{prop.name}} ">{{prop.name}}</label>
                      </div>
                    </div>
                  <div class="col-md-8 ">
                      <div *ngIf="!Edit">
                        <span *ngIf="formVisible && metaDataTemplateMap[selectedFile]!==undefined ">
                          <input id="{{prop.name}}" type="{{prop.details.type}} " [(ngModel)]="Data[prop.name]" class="form-control ">
                        </span>
                      </div>
                      <div *ngIf="Edit">
                        <div *ngIf="prop.details.group ">
                          <span *ngIf="formView">
                            <!--need-->
                            <input id="{{prop.name}}" type="{{prop.details.type}}" [(ngModel)]="Edit[prop.name]" (ngModelChange)="Edit($event)" style=" border-radius:0;"
                             class="form-control">
                          </span>
                        </div>
                        <div *ngIf="!prop.details.group ">
                          <input id="{{prop.name}}" type="text " style=" border-radius:0" class="form-control " readonly>
                        </div>
                     </div>
                    </div>
                  </div>
                </div>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
Run Code Online (Sandbox Code Playgroud)

.ts代码

Data(res) {


    this.Tree['Properties'] = [];

    for (let property in res.properties) {

      var prop = res.properties[property];
      if (prop['properties'] !== undefined) {
        let temp= {};
        if (res['required'].indexOf(property) !== -1) {
          temp['required'] = true;
        }
        else {
          temp['required'] = false;
        }
        temp['name'] = property;
        let template = {};
        temp['details'] = [];
        for (let nestedProps in prop.properties) {
          let nestedProp = {};
          nestedProp['name'] = nestedProps;

          if (prop.properties[nestedProps]['type'] == 'string' || prop.properties[nestedProps]['type'] == 'date-time') {
            prop.properties[nestedProps]['type'] = 'text';
            template[nestedProps] = '';
          }

          if (prop.properties[nestedProps]['type'] == 'integer') {
            prop.properties[nestedProps]['type'] = 'number';
            template[nestedProps] = 0;
          }

          if (prop.properties[nestedProps]['type'] == 'array') {
            prop.properties[nestedProps]['type'] = 'array';
            template[nestedProps] = '';
          }
          if (prop.properties[nestedProps]['group'] == true) {
            if (this.Edit[property] == undefined)
              this.Edit[property] = {};
            this.Edit[property][nestedProps] = '';
          }

          nestedProp['details'] = prop.properties[nestedProps];

          temp['details'].push(nestedProp);
        }
        this.Data[property] = template;
        this.Tree['Properties'].push(temp);
      }
      if (prop['properties'] == undefined) {
        let temp = {};
        if (res['required'].indexOf(property) !== -1) {
          temp['required'] = true;
        }
        else {
          temp['required'] = false;
        }
        temp['name'] = property;
        if (prop['type'] == 'string' || prop['type'] == 'date-time') {
          prop['type'] = 'text';
          this.Data[property] = '';
        }

        if (prop['type'] == 'number') {
          prop['type'] = 'integer';
          this.Data[property] = 0;
        }

        if (prop['group'] == true) {
          this.Edit[property] = '';
        }
        temp['details'] = prop;
        this.Tree['Others'].push(temp);
      }
    }


  }
Run Code Online (Sandbox Code Playgroud)

这里我想要的是1.如果你看到JSON我有

"required": [
    "host", 
    "quantity", 
    "id"
], 
Run Code Online (Sandbox Code Playgroud)

在生成字段时,它必须检查上面提到的字段是否为空或者没有模板或反应形式方法如果字段为空则如何才能实现,那么我们让用户知道字段是空的,我该如何实现?

Sun*_*ngh 5

目标

无需ReactiveTemplate方法验证动态生成的表单输入.

Directive最适合这种要求.Directive有助于将复杂的工作分解成小的独立任务.让我们看看它是如何实现的.

下面提供的实现不需要对现有代码进行任何更改.

1.验证服务

import { Injectable } from '@angular/core';

@Injectable()
export class ValidateService {

  errors = {};

  validate(key: string, value: object) {
    this.errors[key] = value;
  }

  getErrors() {
    let errorList = [];
    Object.keys(this.errors).forEach(key => {
      let value = this.errors[key];
      if ((value == undefined || value == '')  && this.required.find(item=>item == key)) {
        errorList.push({ name: key, error: key + " Field is required" })
      }
    });
    return errorList;
  }

   //All required fields can be maintained here
  required = [
    "host",
    "quantity",
    "id"
  ]

}
Run Code Online (Sandbox Code Playgroud)

2.验证指令

ValidateDirectiveinput如果发生任何变化,则负责收集当前的控制值.此信息将传递给服务类ValidationService.

import { Directive, Host, Input, OnChanges, SimpleChanges, ViewContainerRef, AfterViewInit } from '@angular/core';
import { ValidateService } from './validate.service';

@Directive({
  selector: '[validate]'
})
export class ValidateDirective implements OnChanges {

  constructor(private service: ValidateService, private containerRef: ViewContainerRef) {

  }

  @Input("ngModel") model;

  @Input("validate") element;

  ngOnChanges(changes: SimpleChanges) {

    setTimeout(() => {
      this.service.validate(this.containerRef.element.nativeElement.id, changes.model.currentValue);
    })
  }

}
Run Code Online (Sandbox Code Playgroud)

3.指令用法

ValidateDirective可以与任何具有id和的输入控件一起使用ngModel.

例如:

<input [validate] id="{{prop.name}}" type="{{prop.details.type}}" [(ngModel)]="Edit[prop.name]" (ngModelChange)="Edit($event)" style=" border-radius:0;" class="form-control">
Run Code Online (Sandbox Code Playgroud)

4.组件ts

ValidateService 将被注入组件以获取错误列表.

constructor(private service:ValidateService) {}

  public get errors(){
    return this.service.getErrors();
  }
Run Code Online (Sandbox Code Playgroud)

5.显示错误

由于所有错误都在Component中可用,因此可以在html中显示.

例如:

 <li *ngFor="let error of errors">
     {{error.error}}
 </li>  
Run Code Online (Sandbox Code Playgroud)

注意 - 有很多东西可以进一步增强

  1. 将自定义消息传递给Directive.
  2. Required field list 可以作为@Input传递给Directive

工作示例演示在这里 - https://stackblitz.com/edit/angular-xnbzqd