I'm trying to sanitize the content of some text areas, I cannot use ng-bind-html
because it breaks two way binding (ng-model
does not work at the same time)
Strangely when I apply ng-bind-html
to a model it produces a different result to when I use $sanitize
or $sce
inside of a directive.
Here's a sample I made up
http://plnkr.co/edit/iRvK4med8T9Xqs22BkOe?p=preview
First text area uses ng-bind-html
, the second uses $sanitize
and the third should be the code for the ng-bind-html directive as I ripped out of the AngularJS source code.
"
is only corrected changed to "
when using ng-bind-html, in the other two examples it changes to "
How can I replicate the results of ng-bind-html
in my directive - while keeping the two way binding?
angular.module('sanitizeExample', ['ngSanitize'])
.controller('ExampleController', ['$scope', '$sce',
function($scope, $sce) {
$scope.value = 'This in "quotes" for testing';
$scope.model = 'This in "quotes" for testing';
}
]).directive('sanitize', ['$sanitize', '$parse', '$sce',
function($sanitize, $parse, $sce) {
return {
restrict: 'A',
replace: true,
scope: true,
link: function(scope, element, attrs) {
var process = function(input) {
return $sanitize(input);
//return $sce.getTrustedHtml(input);
};
var processed = process(scope.model);
console.log(processed); // Output here = This in "quotes" for testing
$parse(attrs.ngModel).assign(scope, processed);
//element.html(processed);
}
};
}
])
.directive('sanitizeBindHtml', ['$parse', '$sce',
function($parse, $sce) {
return {
restrict: 'A',
replace: true,
scope: true,
link: function(scope, element, attrs) {
var parsed = $parse(attrs.ngModel);
function getStringValue() {
var value = parsed(scope);
getStringValue.$$unwatch = parsed.$$unwatch;
return (value || '').toString();
}
scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) {
var processed = $sce.getTrustedHtml(parsed(scope)) || '';
$parse(attrs.ngModel).assign(scope, processed)
});
}
};
}
]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-sanitize.js"></script>
<!doctype html>
<html lang="en">
<body ng-app="sanitizeExample">
<div ng-controller="ExampleController">
<textarea ng-bind-html="value"></textarea>
<br/>{{value}}
<br/>
<br/>
<textarea sanitize ng-model="model"></textarea>
<br/>
<br/>
<textarea sanitize-bind-html ng-model="model"></textarea>
</div>
</body>
ngModel
directive seems to be causing issues here for you, and settingpriority
won't fix it. In your final example, copyingngBindHtml
, if you replacengModel
with another name (e.g.bob
,bob="model"
), it will work. plnkr.co/edit/eVA9lvMmwOcWKL1B2fjM?p=preview . Similar for your second directive, except it requires a few other minor changes re: parsing. – McardlengModel
directive. If that doesn't happen, I'll dig into that source when I have a bit more time :) . For the time being, as I mentioned, updating to another attribute works for your other directive, too plnkr.co/edit/lVH1IQAhMfAot116xfiM?p=preview – McardlengModel
when I have a chance. It's a shame changing the attribute doesn't allow two way binding to function still! – Finch