Reputation: 405
Hi Guys I want to write a angular directive which encodes the input text to html.
So that critical characters are converted. For example ö -> ö
I have found this nice library, which I want to use.
My problem is I want to have this convertation only in my model. The user shouldn't see anything from this.
For now I have tried this way. But this doesn't do what I want. I'm new to angular and don't get comfortable with directives. Maybe you can help me.
angular.module('schwimmfestivalAngApp')
.directive('encodedInput', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, ctrl, he) {
element.bind('onblur',
function () {
ctrl.$modelValue = he.encode(ctrl.$viewValue, {
'useNamedReferences': true
});
}
)
;
}
};
});
Upvotes: 0
Views: 310
Reputation: 405
Thanks to Robert for his hints. I think I have figured it out now.
For me it works but not seems to be the perfect way.
This is for now how my directive looks for now.
.directive('encodedInput', function ($window) {
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
if (!ngModel) return; // do nothing if no ng-model
// Specify how UI should be updated
ngModel.$render = function () {
element.html($window.he.decode(ngModel.$modelValue || ''));
};
var inputString = '';
// Listen for change events to enable binding
element.on('blur keyup change', function () {
//Check wether the string has changed. So the & will not be extra encoded.
if (inputString != ngModel.$viewValue) {//Combined without logging
console.log(length);
length = inputString.length;
ngModel.$setViewValue($window.he.encode(ngModel.$viewValue, {
'useNamedReferences': true
}));
}
inputString = ngModel.$viewValue;
});
function read(string) {
}
}
};
}
Upvotes: 0
Reputation: 105039
This is definitely not a beginner's task as you need to have a bit more experience with Angular to make it work as expected.
Manipulating data between view and model in an Angular directive has two parts. One that does conversion from model to view and the other that does conversion from view to model. Basically you should manipulate data in both directions, so your view displays something while your model holds a manipulated value that satisfies your requirements.
You should implement $render
function to aid this part:
ngModelController.$render = function() {
...
}
This part may implement several things. The most important thing in your scenario is probably calling $setViewValue
function
element.on("blur", function(evt) {
ngModelController.$setViewValue(...);
});
Naming may be a bit misleading here as we want data model value to change and not view model value, but read this excerpt directly from docs:
When
$setViewValue
is called, the new value will be staged for committing through the$parsers
and$validators
pipelines. If there are no specialngModelOptions
specified then the staged value sent directly for processing, finally to be applied to$modelValue
and then the expression specified in theng-model
attribute. Lastly, all the registered change listeners, in the$viewChangeListeners
list, are called.
But there're also directive parsers that can manipulate your view value before it gets committed to the model.
ngModelController.$parsers.push(customParser);
function customParser(value) {
return /* some value */;
}
Make sure you thoroughly read the ngModelController documentation.
Make sure you implement several other points mentioned in this documentation by only adding console logs so you can get a grasp of directive execution cycle.
Upvotes: 1