There is SAP (AngularJS and Angular Route) with icon-based navigation made by svg-sprite. So, I hava inline code like this:
This is caused by a combination of AngularJS' dependency of <base href="/" />
and UI routing, when the application is not at its "root" state, the relative hash link in the <use>
element would not correctly resolve.
To get around this, you would need to resolve the xlink:href
to use absolute path. You may do the following:
angular-icon-template.html
<svg class="c-icon" viewBox="0 0 32 32">
<use xlink:href="" ng-attr-xlink:href="{{baseUrl + '#' + iconName}}" />
</svg>
angular-icon.js
angular.module('angularIcon', [])
.directive('angularIcon', {
templateUrl: 'angular-icon-template.html',
scope: { iconName: '@' },
controller: function($scope) {
$scope.baseUrl = window.location.href.replace(window.location.hash, '');
}
});
I was experiencing really similar issue to what you describe with a difference that I would generate my icons <svg>
and <use>
in a directive.
I have been looking for an answer for a better part of today and came up with a workaround to the <use>
and xlink:href
question. Which simply recreates the functionality by inlining the wanted svg.
For the sake of simplicity let's say i have <angular-icon>
directive that receives the name of the icon by an attribute icon-name
<angular-icon icon-name="{{someObject.iconName}}">
working directive now looks as follows:
angular.module('angularIcon', [])
.directive('angularIcon', IconDirective);
function IconDirective(){
return{
template:'',
templateNamespace:'svg',
link:function(scope, element, attributes){
// my icon name comes from $http call so it doesnt exist when initialising the directive,
attributes.$observe( 'iconName', function(iconName){
// let's grab the icon from the sprite
var icon = angular.element( document.getElementById( iconName ) );
// let's clone it so we can modify it if we want
var iconClone = icon.clone();
var namespace = "http://www.w3.org/2000/svg";
// manually create the svg element and append the inlined icon as no other way worked
var svg = document.createElementNS( namespace, 'svg' );
svg.setAttribute( 'viewBox', '0 0 32 32' );
svg.setAttribute( 'xml:space', 'preserve' );
svg.appendChild( iconClone[0] );
// let's add the newly created svg+icon to the directive's element
element[0].appendChild( svg );
});
},
scope:{
iconName: '@'
}
}
}