Reputation: 13397
So I am trying to create a directive that has an ng-include in it. The directive currently looks like this:
.directive('kdTest', function () {
return {
restrict: 'A',
scope: {
kit: '=kdTest',
garment: '=kdGarment'
},
template: '<div></div>',
link: function (scope, element, attrs) {
console.log(scope.kit);
console.log(scope.garment);
}
}
});
what I want to do is change the template to look more like this:
.directive('kdTest', function () {
return {
restrict: 'A',
scope: {
kit: '=kdTest',
garment: '=kdGarment'
},
template: '<div ng-include="'/assets/garments/' + garment.slug + '.svg'"></div>',
link: function (scope, element, attrs) {
console.log(scope.kit);
console.log(scope.garment);
}
}
});
but as you can see, the single quotes are going to cause me problems. Can someone help me fix that?
Also, I need to be able to access the svg element from inside the directive.
Update 1
So, I have changed my directive to this:
.directive('kdTest', function () {
var colours,
design,
garment;
// Function to show our selected design
var showDesign = function (element) {
// Get our image
var svg = element.find('svg');
console.log(svg.length);
// If we have an image
if (svg.length) {
///-- removed for brevity --//
}
};
return {
restrict: 'A',
scope: {
kit: '=kdTest',
garment: '=kdGarment'
},
template: '<div ng-include="svgPath"></div>',
link: function (scope, element, attrs) {
// Attach our scope to our global variables
colours = scope.colours;
design = scope.design;
garment = scope.garment;
// Create our svgPath
scope.svgPath = 'assets/garments/' + scope.garment.slug + '.svg';
// Show our selected design
showDesign(element);
}
}
});
So in my function showDesign the console.log(svg.length) returns 0. How can I get it to actually see the svg?
Upvotes: 2
Views: 1387
Reputation: 49620
ng-include
includes the content asyncronously, and so when the link
function of the directive runs, the DOM elements of the ng-include
(incl. svg
) are still not there.
Luckily, ng-include
provides an onload
event, and so you could do:
template: '<div ng-include="svgPath" onload="svgLoaded()"></div>',
link: function(scope, element){
// rest of your link function...
scope.svgLoaded = function(){
// Show our selected design
showDesign(element);
}
}
EDIT: (to complete the answer):
the inner quotes should be escaped (as suggested in another answer), like so:
ng-include="\'/some/path\'"
or, better - the path could be constructed in the link
function and the variable assigned to ng-include
.
Upvotes: 1
Reputation: 72967
Simple. Escape the quotes.
Replace:
template: '<div ng-include="'/assets/garments/' + garment.slug + '.svg'"></div>',
With:
template: '<div ng-include="\'/assets/garments/\' + garment.slug + \'.svg\'"></div>',
Or:
template: "<div ng-include=\"'/assets/garments/\' + garment.slug + '.svg'\"></div>',
Or better yet, just link the template to a html file:
templateUrl: "some/html/file.html",
That contains the include:
<div ng-include="garmentPath"></div>
And set the path in a variable, in the link
function:
scope.garmentPath = '/assets/garments/' + scope.garment.slug + '.svg';
To access the svg element, you may want to use a html file, as I suggested.
<div id="mySvg" ng-include="garmentPath"></div>
Then you can use jQuery to get the element: $('#mySvg svg');
Or native JS: document.getElementById("mySvg").getElementsByTagName("svg")
Upvotes: 3