验证 angular 表单和 Json(已实施基本验证)
To Validate angular form and Json(Basic validaton already implemented)
当我们将鼠标悬停在 table 的第一列上时,会出现一个工具提示,然后单击工具提示垫对话框中的按钮会打开。
该对话框包含 2 个部分左侧和编辑 json 和。左边是选中哪一行,右边显示的是对应的数据json。
1) 基本表单验证有效,但我需要显示一些消息(如果表单无效)以防用户编辑 json 并尝试单击按钮。
(尝试使用 blur [ngModelOption] [ngFormOption] onUpdate 属性 但无法实现)
对于 json 部分,基本验证也有效,但对于以下几点,如何提供验证:
1) 如果我将密钥设为空字符串,它不会验证。
2) 我怎样才能强制指定一个特定的密钥。
Stackblitz link
https://stackblitz.com/edit/angular-mat-tooltip-qxxgcp?file=app%2Falert-dialog%2Falert-dialog.component.html
警报摘录-dialog.component.ts
<form #jsonform="ngForm" (ngSubmit)="onAddNewAlert()">
<json-input [(ngModel)]="data.data[incomingSelectedAlert].conditionals" name="result"></json-input>
<button type="submit" class="btn btn-success alertButtonSubmit" [disabled]="jsonform.invalid">Add As New Alert</button>
</form>
json-input.component (我有 NG_VALIDATORS 和 valdidate 函数执行基本的 json 验证)
@Component({
selector: 'json-input',
template:
`
<style>
textarea {
height: 421px;
width: 480px;
resize: none;
}
</style>
<textarea
[value]="jsonString"
(change)="onChange($event)"
(keyup)="onChange($event)">
</textarea>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => JsonInputComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => JsonInputComponent),
multi: true,
}]
})
export class JsonInputComponent implements ControlValueAccessor, Validator {
private jsonString: string;
private parseError: boolean;
private data: any;
// this is the initial value set to the component
public writeValue(obj: any) {
if (obj) {
this.data = obj;
// this will format it with 4 character spacing
this.jsonString = JSON.stringify(this.data, undefined, 4);
}
}
// registers 'fn' that will be fired wheb changes are made
// this is how we emit the changes back to the form
public registerOnChange(fn: any) {
this.propagateChange = fn;
}
// validates the form, returns null when valid else the validation object
// in this case we're checking if the json parsing has passed or failed from the onChange method
public validate(c: FormControl) {
return (!this.parseError) ? null : {
jsonParseError: {
valid: false,
},
};
}
// not used, used for touch input
public registerOnTouched() { }
// change events from the textarea
private onChange(event) {
// get value from text area
let newValue = event.target.value;
try {
// parse it to json
this.data = JSON.parse(newValue);
this.parseError = false;
} catch (ex) {
// set parse error if it fails
this.parseError = true;
}
// update the form
this.propagateChange(this.data);
}
// the method set in registerOnChange to emit changes back to the form
private propagateChange = (_: any) => { };
}
我已经通过以下步骤完成了您需要的操作:
- 将 json 表单转换为反应式表单而不是模板表单(使用模板表单并在 TypeScript 代码中检索
NgForm
指令不是一个好习惯)
将 forbiddenFields
(包含空字符串,因为它是 JS 中的实际有效键)和 mandatoryFields
添加到 JsonInputComponent
mandatoryFields: string[] = ["conditionals", "offset", "alert"];
forbiddenFields: string[] = [""];
在onChange
函数中实现字段检查:
private onChange(event) {
// get value from text area
let newValue = event.target.value;
try {
// parse it to json
this.data = JSON.parse(newValue);
const datakeys = Object.keys(this.data);
const containsForbiddenFields = datakeys.some(x => this.forbiddenFields.indexOf(x) >= 0);
const containsMandatoryFields = this.mandatoryFields.every(x => datakeys.indexOf(x) >= 0);
this.parseError = containsForbiddenFields || !containsMandatoryFields;
} catch (ex) {
// set parse error if it fails
this.parseError = true;
}
// update the form
this.propagateChange(this.data);
}
对于完整的工作解决方案,这里是分叉的 Stackblitz
我已按照以下步骤操作并根据要求更新了您的代码,它似乎工作正常:
For adding validations to check empty string and mandatory keys in
nested objects, I have added logic on ngOnInit() method when value
of form changes in AlertDialogComponent with the help of control value
accessor.
添加了这些变量以验证表单并获取 JSON 对象的键,
isFormValid = true;
mandatoryField = ['conditionals', 'offset', 'alert', 'mTitle'];
allMandatoryFieldsExists: boolean;
在这里附上我的解决方案和主要代码,Stackblitz
this.jsonform.statusChanges.subscribe(() => {
let data = this.jsonform.value.result;
let keys = [];
if(data) {
for(var i in data) {
keys.push(i);
if(i === 'offset' && data[i] === '') {
this.isFormValid = false;
return;
} else {
this.isFormValid = true;
}
if(i === 'conditionals') {
for(var j in data[i][0]) {
keys.push(j);
if(data[i][0][j] === '') {
this.isFormValid = false;
return;
} else {
this.isFormValid = true;
}
}
}
if(i === 'alert') {
for(var j in data[i]) {
keys.push(j);
if(data[i][j] === '') {
this.isFormValid = false;
return;
} else {
this.isFormValid = true;
}
}
}
}
this.allMandatoryFieldsExists = this.mandatoryField.every(x => keys.indexOf(x) >= 0);
}
if(this.jsonform.dirty && (!this.isFormValid || !this.allMandatoryFieldsExists)){
console.log("form is dirty and not valid")
// this.alertService.error("Json not correct. Please fix!");
}else{
console.log("form is dirty but valid")
}
});
当我们将鼠标悬停在 table 的第一列上时,会出现一个工具提示,然后单击工具提示垫对话框中的按钮会打开。
该对话框包含 2 个部分左侧和编辑 json 和。左边是选中哪一行,右边显示的是对应的数据json。
1) 基本表单验证有效,但我需要显示一些消息(如果表单无效)以防用户编辑 json 并尝试单击按钮。 (尝试使用 blur [ngModelOption] [ngFormOption] onUpdate 属性 但无法实现)
对于 json 部分,基本验证也有效,但对于以下几点,如何提供验证:
1) 如果我将密钥设为空字符串,它不会验证。
2) 我怎样才能强制指定一个特定的密钥。
Stackblitz link https://stackblitz.com/edit/angular-mat-tooltip-qxxgcp?file=app%2Falert-dialog%2Falert-dialog.component.html
警报摘录-dialog.component.ts
<form #jsonform="ngForm" (ngSubmit)="onAddNewAlert()">
<json-input [(ngModel)]="data.data[incomingSelectedAlert].conditionals" name="result"></json-input>
<button type="submit" class="btn btn-success alertButtonSubmit" [disabled]="jsonform.invalid">Add As New Alert</button>
</form>
json-input.component (我有 NG_VALIDATORS 和 valdidate 函数执行基本的 json 验证)
@Component({
selector: 'json-input',
template:
`
<style>
textarea {
height: 421px;
width: 480px;
resize: none;
}
</style>
<textarea
[value]="jsonString"
(change)="onChange($event)"
(keyup)="onChange($event)">
</textarea>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => JsonInputComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => JsonInputComponent),
multi: true,
}]
})
export class JsonInputComponent implements ControlValueAccessor, Validator {
private jsonString: string;
private parseError: boolean;
private data: any;
// this is the initial value set to the component
public writeValue(obj: any) {
if (obj) {
this.data = obj;
// this will format it with 4 character spacing
this.jsonString = JSON.stringify(this.data, undefined, 4);
}
}
// registers 'fn' that will be fired wheb changes are made
// this is how we emit the changes back to the form
public registerOnChange(fn: any) {
this.propagateChange = fn;
}
// validates the form, returns null when valid else the validation object
// in this case we're checking if the json parsing has passed or failed from the onChange method
public validate(c: FormControl) {
return (!this.parseError) ? null : {
jsonParseError: {
valid: false,
},
};
}
// not used, used for touch input
public registerOnTouched() { }
// change events from the textarea
private onChange(event) {
// get value from text area
let newValue = event.target.value;
try {
// parse it to json
this.data = JSON.parse(newValue);
this.parseError = false;
} catch (ex) {
// set parse error if it fails
this.parseError = true;
}
// update the form
this.propagateChange(this.data);
}
// the method set in registerOnChange to emit changes back to the form
private propagateChange = (_: any) => { };
}
我已经通过以下步骤完成了您需要的操作:
- 将 json 表单转换为反应式表单而不是模板表单(使用模板表单并在 TypeScript 代码中检索
NgForm
指令不是一个好习惯) 将
forbiddenFields
(包含空字符串,因为它是 JS 中的实际有效键)和mandatoryFields
添加到JsonInputComponent
mandatoryFields: string[] = ["conditionals", "offset", "alert"]; forbiddenFields: string[] = [""];
在
onChange
函数中实现字段检查:private onChange(event) { // get value from text area let newValue = event.target.value; try { // parse it to json this.data = JSON.parse(newValue); const datakeys = Object.keys(this.data); const containsForbiddenFields = datakeys.some(x => this.forbiddenFields.indexOf(x) >= 0); const containsMandatoryFields = this.mandatoryFields.every(x => datakeys.indexOf(x) >= 0); this.parseError = containsForbiddenFields || !containsMandatoryFields; } catch (ex) { // set parse error if it fails this.parseError = true; } // update the form this.propagateChange(this.data); }
对于完整的工作解决方案,这里是分叉的 Stackblitz
我已按照以下步骤操作并根据要求更新了您的代码,它似乎工作正常:
For adding validations to check empty string and mandatory keys in nested objects, I have added logic on ngOnInit() method when value of form changes in AlertDialogComponent with the help of control value accessor.
添加了这些变量以验证表单并获取 JSON 对象的键,
isFormValid = true;
mandatoryField = ['conditionals', 'offset', 'alert', 'mTitle'];
allMandatoryFieldsExists: boolean;
在这里附上我的解决方案和主要代码,Stackblitz
this.jsonform.statusChanges.subscribe(() => {
let data = this.jsonform.value.result;
let keys = [];
if(data) {
for(var i in data) {
keys.push(i);
if(i === 'offset' && data[i] === '') {
this.isFormValid = false;
return;
} else {
this.isFormValid = true;
}
if(i === 'conditionals') {
for(var j in data[i][0]) {
keys.push(j);
if(data[i][0][j] === '') {
this.isFormValid = false;
return;
} else {
this.isFormValid = true;
}
}
}
if(i === 'alert') {
for(var j in data[i]) {
keys.push(j);
if(data[i][j] === '') {
this.isFormValid = false;
return;
} else {
this.isFormValid = true;
}
}
}
}
this.allMandatoryFieldsExists = this.mandatoryField.every(x => keys.indexOf(x) >= 0);
}
if(this.jsonform.dirty && (!this.isFormValid || !this.allMandatoryFieldsExists)){
console.log("form is dirty and not valid")
// this.alertService.error("Json not correct. Please fix!");
}else{
console.log("form is dirty but valid")
}
});