代码之家  ›  专栏  ›  技术社区  ›  Madpop

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

  •  8
  • Madpop  · 技术社区  · 6 年前

    我面临一个现有应用程序的问题,下面是我的场景 我有下面的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>
    

    .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);
          }
        }
    
    
      }
    

    我要的是1。如果你在json中看到

    "required": [
        "host", 
        "quantity", 
        "id"
    ], 
    

    在生成字段时,它必须检查上述字段是否为空,不使用模板或反应式表单方法。如果字段为空,那么我们如何让用户知道字段为空?我如何才能做到这一点?

    1 回复  |  直到 6 年前
        1
  •  5
  •   Sunil Singh    6 年前

    瞄准

    动态生成表单输入的验证 Reactive Template 接近。

    解决方案

    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"
      ]
    
    }
    

    2。验证指令

    ValidateDirective 负责收集 input 控制是否发生任何更改。此信息将传递给服务类 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);
        })
      }
    
    }
    

    三。指令用法

    验证指令 可与任何输入控件一起使用 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">
    

    4。组件ts

    ValidateService 将被注入到组件中以获取错误列表。

    constructor(private service:ValidateService) {}
    
      public get errors(){
        return this.service.getErrors();
      }
    

    5。显示错误

    由于组件中存在所有错误,因此可以在HTML中显示。

    前任:

     <li *ngFor="let error of errors">
         {{error.error}}
     </li>  
    

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

    1. 将自定义消息传递到 指令 .
    2. Required field list 可以作为@input传递给指令

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