I want to implement a "TrimDirective", which deletes leading and trailing spaces from input fields, with Angular 2 RC 5 and model driven / reactive forms.
I managed to change the value of the input field, however I don't get a new value in the component in myForm.valueChanges()
.
See this plunker: http://plnkr.co/edit/ruzqCh?p=preview
How can I trigger a update of the formGroup when the directive changes the value?
template:
<form [formGroup]="myForm">
<input formControlName="name" trim>
</form>
latest value: -{{ latestValue }}-
component:
@Component({
selector: 'my-app',
templateUrl: 'app/app.html'
})
export class AppComponent implements OnInit {
private myForm: FormGroup;
private latestValue: string;
ngOnInit() {
this.myForm = new FormGroup({
name: new FormControl(),
});
this.myForm.valueChanges.subscribe(v => this.latestValue = v.name)
}
}
directive:
@Directive({
selector: '[trim]'
})
export class TrimDirective {
private el: any;
constructor(
el: ElementRef
){
this.el = el.nativeElement;
}
@HostListener('keypress')
onEvent() {
setTimeout(() => { // get new input value in next event loop!
let value: string = this.el.value;
if(value && (value.startsWith(' ') || value.endsWith(' '))) {
console.log('trim!');
this.el.value = value.trim();
}
},0);
}
}
Setup in reactive formslink The [formControl] directive links the explicitly created FormControl instance to a specific form element in the view, using an internal value accessor. The following component implements an input field for a single control, using reactive forms.
Setting or Updating of Reactive Forms Form Control values can be done using both patchValue and setValue. However, it might be better to use patchValue in some instances. patchValue does not require all controls to be specified within the parameters in order to update/set the value of your Form Controls.
Template Driven Forms are based only on template directives, while Reactive forms are defined programmatically at the level of the component class. Reactive Forms are a better default choice for new applications, as they are more powerful and easier to use.
You can create and trigger a change event on the element to tell angular to update the model value.
let event: Event = document.createEvent("Event");
event.initEvent('input', true, true);
Object.defineProperty(event, 'target', {value: this.elementRef.nativeElement, enumerable: true});
this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'dispatchEvent', [event]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With