我正在面对现有应用程序的问题,以下是我的情况 我具有以下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"
],
在生成字段时,必须使用模板或反应形式方法来检查上述字段是否为空,如果字段为空,那么如何让用户知道字段为空,我该如何完成这个吗?
答案 0 :(得分:5)
目标
未经Reactive
或Template
方法验证动态生成的表单输入。
解决方案
Directive
将是此类要求的最佳选择。 Directive
有助于将复杂的工作分解成小的独立任务。让我们看看如何实现它。
下面提供的实现无需更改现有代码。
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"
]
}
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);
})
}
}
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">
ValidateService
将被注入组件以获取错误列表。
constructor(private service:ValidateService) {}
public get errors(){
return this.service.getErrors();
}
由于所有错误都在组件中可用,因此可以在html中显示。
ex:
<li *ngFor="let error of errors">
{{error.error}}
</li>
注意-有很多可以进一步增强的功能,例如
- 将自定义消息传递到
Directive
。Required field list
可以作为@Input传递给指令
有效的示例演示在这里-https://stackblitz.com/edit/angular-xnbzqd