Reputation: 1493
I want to add a pre-processing step to AngularJS before it updates any HTML. For the sake of simplicity, let's have it bold all instances of hello
.
That is, if we let $scope.text = "hello world!"
, we want somehow to have
{{ text }}
evaluate during the $digest
cycle into
<b>hello</b> world!
If $scope.text
is changed, this would of course update as appropriate.
How would this be done? Preferably, it would be a directive, so that any expressions inside a <div boldhello></div>
would be processed.
Upvotes: 4
Views: 506
Reputation: 18803
datasage's comment is spot on - this is a great place for a filter. Here's a basic filter adapted from the documentation examples that replaces any instance of hello
with one surrounded by bold tags:
(function(angular) {
'use strict';
angular.module('myFilterApp', [])
.filter('boldHello', function($sce) {
return function(input) {
input = input || '';
var out = input.replace(/hello/gi, function(text) {
return '<b>' + text + '</b>';
});
return out;
};
})
.controller('MyController', ['$scope', function($scope) {
$scope.greeting = 'Oh, hello, my friend.';
}]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myFilterApp">
<div ng-controller="MyController">
<input ng-model="greeting" type="text"><br>
No filter: {{greeting}}<br>
Bold: {{greeting | boldHello}}<br>
</div>
</body>
But alas, the tags are printed in the output! That's because Angular keeps you safe from accidental HTML injection (which might contain script
tags), so we need to mark this explicitly safe. You mark it safe with trustAsHtml
, and we need to put the result into your template using the ng-bind-html
directive.
(function(angular) {
'use strict';
angular.module('myFilterApp', [])
.filter('boldHello', function($sce) {
return function(input) {
input = input || '';
var out = input.replace(/hello/gi, function(text) {
return '<b>' + text + '</b>';
});
return $sce.trustAsHtml(out);
};
})
.controller('MyController', ['$scope', function($scope) {
$scope.greeting = 'Oh, hello, my friend.';
}]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myFilterApp">
<div ng-controller="MyController">
<input ng-model="greeting" type="text"><br>
No filter: {{greeting}}<br>
Bold: <span ng-bind-html="greeting | boldHello"></span><br>
</div>
</body>
Upvotes: 2