What's the difference between ngModel.$modelValue and ngModel.$viewValue
I have the following ckEditor directive. At the bottom are two variations that I have seen from examples on how to set the data in the editor:
app.directive('ckEditor', [function () {
return {
require: '?ngModel',
link: function ($scope, elm, attr, ngModel) {
var ck = null;
var config = attr.editorSize;
if (config == 'wide') {
ck = CKEDITOR.replace(elm[0], { customConfig: 'config-wide.js' });
} else {
ck = CKEDITOR.replace(elm[0], { customConfig: 'config-narrow.js' });
}
function updateModel() {
$scope.$apply(function () {
ngModel.$setViewValue(ck.getData());
});
}
$scope.$on('modalObjectSet', function (e, modalData) {
// force a call to render
ngModel.$render();
});
ck.on('change', updateModel);
ck.on('mode', updateModel);
ck.on('key', updateModel);
ck.on('dataReady', updateModel);
ck.on('instanceReady', function () {
ngModel.$render();
});
ck.on('insertElement', function () {
setTimeout(function () {
$scope.$apply(function () {
ngModel.$setViewValue(ck.getData());
});
}, 1000);
});
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
};
ngModel.$render = function (value) {
ck.setData(ngModel.$viewValue);
};
}
};
}])
Can someone tell me what is the difference between:
ck.setData(ngModel.$modelValue);
ck.setData(ngModel.$viewValue);
And which should I use. I looked at the angular documentation and it says:
$viewValue
Actual string value in the view.
$modelValue
The value in the model, that the control is bound to.
I have no idea what the author meant when he wrote this in the document :-(
Solution 1:
You are looking at the correct documentation, but it might just be that you're a little confused. The $modelValue
and $viewValue
have one distinct difference. It is this:
As you already noted above:
$viewValue:
Actual string (or Object) value in the view.$modelValue:
The value in the model, that the control is bound to.
I'm going to assume that your ngModel is referring to an <input />
element...? So your <input>
has a string value that it displays to the user, right? But the actual model might be some other version of that string. For example, the input might be showing the string '200'
but the <input type="number">
(for example) will actually contain a model value of 200
as an integer. So the string representation that you "view" in the <input>
is the ngModel.$viewValue
and the numeric representation will be the ngModel.$modelValue
.
Another example would be a <input type="date">
where the $viewValue
would be something like Jan 01, 2000
and the $modelValue
would be an actual javascript Date
object that represents that date string. Does that make sense?
I hope that answers your question.
Solution 2:
You can see things like this :
-
$modelValue
is your external API, that is to say, something exposed to your controller. -
$viewValue
is your internal API, you should use it only internally.
When editing $viewValue
, the render method won't be called, because it is the "rendered model". You will have to do it manually, whereas the rendering method will be called automatically upon $modelValue
modifications.
However, the information will remain consistent, thanks to $formatters
and $parsers
:
- If you change
$viewValue
,$parsers
will translate it back to$modelValue
. - If you change
$modelValue
,$formatters
will convert it to$viewValue
.