Reputation: 881
I'm using SVG icons contained in a sprite, like below.
<div class="py-3">
<svg-icon><src href="sprite.svg#si-glyph-bullet-checked-list"/></svg-icon>
<span>Tasks</span>
</div>
And it works fine, yet when I rewrite it to Angular directive:
app.directive('ngxTileIcon', function () {
return function (scope, element, attrs) {
var tileIcon = attrs['ngxTileIcon'];
var tileCaption = element.text();
element.text('');
element.addClass('py-3');
element.append(
$('<svg-icon/>').append(
$('<src/>').attr('href', 'sprite.svg#si-glyph-' + tileIcon)
),
$('<span/>').text(tileCaption)
);
};
});
And use it:
<div ngx-tile-icon="bullet-checked-list">Tasks</div>
Basically, I'm getting the same markup but Google Chrome does not display that an SVG element has been added to the DOM. When using non-Angular approach, it does. Finally, when using Angular directive, the icon is not displayed.
SOLVED
I just changed the approach - instead of adding the markup to the element, I'm directly replacing its content with html()
. Now it works as expected.
app.directive('ngxTileIcon', function () {
return function (scope, element, attrs) {
var tileIcon = attrs['ngxTileIcon'];
var tileCaption = element.text();
var $tempDiv = $('<div/>');
element.addClass('py-3');
$tempDiv.append(
$('<svg-icon/>').append(
$('<src/>').attr('href', 'sprite.svg#si-glyph-' + tileIcon)
),
$('<span/>').text(tileCaption)
);
element.html($tempDiv.html());
};
});
Upvotes: 0
Views: 1845
Reputation: 5188
Damian has pointed out that this answer is wrong, but I'll leave it up to prevent anyone else making the same mistake!
<svg-icon> is an Angular directive and not a native HTML element, so adding it in using jQuery will not trigger Angular's logic and you're just left with nothing.
In general with Angular 1.x (assuming you're using 1.x?), you should give it a template field which will create the icon based on the input:
app.directive( "myDirective", function() {
return {
template: "<div class='py-3'><svg-icon><src href='sprint.svg#si-glyph-{{ tileIcon }}'></src></svg-icon></div>"
scope: {
tileIcon: "<"
}
};
});
This should bind the "tileIcon" variable to the supplied attribute in the parent element, and then inject it in the template, with databinding so that it updates when the parent updates. });
Upvotes: 1
Reputation: 77904
Its not what you are asking but it can help you to sort things out.
Take a look on this simple example how works svg builder with directive.
<button>
<my-icon
icon="arrow_left"
size="18"
style="fill:#37393B;"></my-icon>
</button>
directive:
app.directive('myIcon', function () {
var shapes = {
'arrow_left':
'viewBox="-358 231.3 125 133" >' +
'<rect x="-342.8" y="262.7" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 -315.0274 678.5285)" width="89.5" height="22.6"/>' +
'<rect x="-342.8" y="309.9" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 -736.0015 337.5721)" width="89.5" height="22.6"/>' +
'</svg>'
//, other svgs
};
return {
restrict: 'E',
link: function (scope, element, attr) {
var icon, size;
var render = function () {
icon = attr.icon;
var ss = icon.match(/ic_(.*)_([0-9]+)px.svg/m);
if (ss !== null) {
icon = ss[1];
size = ss[2];
}
// size
if (attr.size !== undefined)
size = attr.size;
else if (size !== null)
size = 24;
// render
element.html('<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + size + '" x="0px" y="0px" ' + shapes[icon]);
};
render();
}
};
});
Upvotes: 0