问题
I'm trying to convert every string input to null upon cahnge. So i create a directive to listen on every change and assign null to empty string.
And here is the HTML
<form [formGroup]="form" class="mt-4 p-2" (ngSubmit)="onSubmit()">
<input nbInput fullWidth fieldSize="small" shape="semi-round" formControlName="AuthorityNum" EmptyToNull>
</form>
Here is the directive code:
import { Directive, Input, HostListener, ElementRef } from
'@angular/core';
@Directive({
selector: '[EmptyToNull]'
})
export class NullValueDirective {
constructor() {
}
@HostListener('change', ['$event.target.value']) onKeyDowns(value) {
if (value === '') {
value = null;
console.log(value) // print: null
}
}
}
It looks like it change the value to null
But when i submit the form and inspect the form.value it appears as empty string again.
why?
Update:
Here is my submit function:
onSubmit() {
// TODO: Send to server
this.form.value.AuthorityNum === '' // true
}
Here is the code at stackblitz: https://stackblitz.com/edit/angular-ilcg7y
回答1:
There are couple of issues with your code:
The directive needs to emit the value back so that can be bound to the respective form control:
export class NullValueDirectiveDirective { @Output('EmptyToNull') response = new EventEmitter<string>(); @HostListener('keyup', ['$event']) onKeyDowns(event: KeyboardEvent) { this.response.emit(null); } }
Next on your template you need to bind to the emitted value:
<input formControlName="AuthorityNum" (EmptyToNull) = "form.controls.AuthorityNum.value = $event">
回答2:
I am trying to understand your aim using the EmptyToNull directive.
If you're trying to avoid empty values to be passed in the form, you can better use validators when you build the form in your ts:
this.form = this.formbuilder.group({
date: [''],
AuthorityNum: ['', [Validators.required]],
});
See more on validators: https://angular.io/api/forms/Validators
When submitting the form, you can also check the values fullfill the validators you've set:
onSubmit() {
Object.keys(this.form.controls).forEach(field => {
let control = this.form.get(field);
control.markAsTouched({
onlySelf: true
});
control.updateValueAndValidity();
});
}
Also you can try on the following approaches in your TS when submitting the form or detecting changes in the form:
this.form.reset({
date: { value: '' },
AuthorityNum: { value: null }
});
Or even applied in your directive:
this.form.controls['AuthorityNum'].setValue(null);
Hope it helps!
回答3:
Directive code:
import { Directive, HostListener, Self } from '@angular/core';
import { NgControl } from '@angular/forms';
@Directive({ selector: '[EmptyToNull]' })
export class EmptyToNullDirective {
constructor(@Self() private ngControl: NgControl) {}
@HostListener('keyup', ['$event']) onKeyDowns(event: KeyboardEvent) {
if (this.ngControl.value?.trim() === '') {
this.ngControl.reset(null);
}
}
}
Template:
<input nbInput fullWidth fieldSize="small" shape="semi-round" formControlName="AuthorityNum" EmptyToNull>
来源:https://stackoverflow.com/questions/57902512/why-set-empty-string-as-null-in-reactive-form-become-empty-string