I'm an author of angular-input-modified directive.
This directive is used to track model's value and allows to check whether the value was modified and also provides reset()
function to change value back to the initial state.
Right now, model's initial value is stored in the ngModelController.masterValue
property and ngModelController.reset()
function is provided. Please see the implementation.
I'm using the following statement: eval('$scope.' + modelPath + ' = modelCtrl.masterValue;');
in order to revert value back to it's initial state. modelPath
here is actually a value of ng-model
attribute. This was developed a way back and I don't like this approach, cause ng-model
value can be a complex one and also nested scopes will break this functionality.
What is the best way to refactor this statement? How do I update model's value directly through the ngModel controller's interface?
The best solution I've found so far is to use the $parse service in order to parse the Angular's expression in the
ng-model
attribute and retrieve the setter function for it. Then we can change the model's value by calling this setter function with a new value.Example:
This works much more reliably than
eval()
.If you have a better idea please provide another answer or just comment this one. Thank you!
[previous answer]
I had trouble with this issue today, and I solved it by triggering and sort of hijacking the
$parsers
pipeline using a closure.Then for resetting the model you need to trigger the pipeline by changing the
$viewValue
withmodelCtrl.$setViewValue('newViewValue')
.By using
$setViewValue()
, you will trigger the$parsers
pipeline. The function I wrote in the first code block will then be executed withval = getViewValue(model)
, at which point it would try to parse it into something to use for your$modelValue
according the logic in there. But at this point, the variable in the closure hijacks the parser and uses it to completely overwrite the current $modelValue.At this point,
val
is not used in the$parser
, but it will still be the actual value that is displayed in the DOM, so pick a nice one.Let me know if this approach works for you.
[edit]
It seems that ngModel.$commitViewValue should trigger the $parsers pipeline as well, I tried quickly but couldn't get it to work.