Reputation: 1004
I bound a variable to an input filed using interpolation (value of variable gets reflected in the input field). The variable gets updated automatically in the background whenever the according value in the database changes.
I would like to prevent Angular from applying the changes of the variable to the input field IF the user is currently editing this field. Otherwise, the editing of the user will be overwritten.
(In other words: I would like that Angular checks if the input field is currently flagged with ng-pristine and not ng-dirty before it updates the value.)
What is the easiest why to achieve that?
Idea: Shouldn't it be possible to implement a directive that is equal to ngModel but checks if the class ng-dirty is set before applying the value?
Optimal Solution: Having a directive, that does two-way-data-binding like ngModel. The directive applies changes within the model to the view if the "ng-dirty" flag is not set for the view. The directive applies changes within the view to the model if the view loses its focus (if the blur event gets triggered).
Upvotes: 3
Views: 2186
Reputation: 209102
One way I could see doing this is to just create a directive the injects the NgModel
. You can use it to write to the view, in this case the input, and to write to the model if you want. You can also check the model if it is pristine and not dirty. For example
import { Directive, OnInit, OnDestroy, Self } from '@angular/core';
import { NgModel } from '@angular/forms';
@Directive({
selector: '[updateInput][ngModel]'
})
export class UpdateDirective implements OnInit, OnDestroy {
private interval: any;
constructor(@Self() private model: NgModel) {}
ngOnInit() {
let counter = 0;
this.interval = setInterval(() => {
console.log(`pristine: ${this.model.pristine}, dirty: ${this.model.dirty}`);
if (this.model.pristine && !this.model.dirty) {
counter += 2;
this.model.valueAccessor.writeValue(`It's been ${counter} seconds...`);
// the model will not be initially updated until the first editing by the user.
// If you want the model updated when you write to the input, call the following.
// Or comment it out if you don't want this behavior.
this.model.viewToModelUpdate(`It's been ${counter} seconds...`);
} else {
clearInterval(this.interval);
}
}, 2000);
}
ngOnDestroy() {
if (this.interval) {
clearInterval(this.interval);
}
}
}
Here's a Plunker.
Note: The selector for this directive is not great. It is just a POC. If you want a more accurate selector to handle all use cases, you might want to check out the one used for DefaultControlValueAccessor
Upvotes: 1