简体   繁体   中英

AngularJS directives, templates and ng-include

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?

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")

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM