Reputation: 2392
I have a directive and I´m replacing IMG urls with img src to display images inline
function message($filter) {
var directive = {
restrict: 'EA',
scope: {
data: '='
},
link: function(scope, elem, attrs) {
scope.data.content = scope.data.content.replace(/(https?:\/\/\S+(\.png|\.jpeg|\.jpg|\.gif))/g, "<img src='$1' alt=''>");
},
template: '<span>{{data.nickname}}:</span> {{data.content}}'
};
return directive;
}
but instead of seeing the image inline I´m seeing the HTML tag as text I´m investigating $sce but I´m not sure how to use it inside a directive.
Upvotes: 3
Views: 1125
Reputation: 11725
So, a more angular and safer way to do this is to not write html to the template directly. Instead, you can use curly brackets to put the image url in the template like this:
template: `
<span>{{data.nickname}}:</span>
<img ng-if="{{data.hasImage}}" src="{{data.url}}" alt="">
`
This preserves template/data separation.
The way you had it, you're putting yourself at risk of XSS. There's a reason angular makes you jump through hoops in order to put generated html in a template. If a user ever is able to upload an image with js in the url, your site could be hacked. Angular's normal templating prevents this kind of attack automatically.
If you need multiple images, you can put add a url property to each object in your data, put the data array on the scope, then use ng-repeat to render the array of objects.
Upvotes: 1
Reputation: 23849
You are closer!. You are right about working with ngSanitize
module.
It basically allows you to write raw HTML in your template (using ng-bind-html
directive). You need to include it in your page, and declare it as a dependency in your module like this:
<!-- HTML -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-sanitize/1.6.2/angular-sanitize.min.js"></script>
// JavaScript
angular.module("yourapp", ['ngSanitize']);
And then, bind your HTML content in a div
(or whatever) using ng-bind-html
directive like this:
template: '<span>{{data.nickname}}:</span> <div ng-bind-html="data.content"></div>'
Now, the raw HTML contents of data.content
will be replaced as is in your directive's template. Here is a working plunker for your reference.
Upvotes: 8