mtpultz
mtpultz

Reputation: 18248

AngularJS implementing dynamic templating - confirm understanding of $compile and link

I'm trying to understand dynamic templateUrl at a high-level since I've only just begun playing around with AngularJS. I found this project on GitHub which does exactly what I'd like to be doing. Below the snippet I've added a bit of text regarding my understanding of the flow of execution of $compile and link, to make sure I understand it (general AngularJS compile and then applied to snippet).

    .directive('formField', [ '$http', '$compile', function( $http, $compile ) {

    var getTemplateUrl = function( field ) {
        var type = field.field_type;
        var templateUrl = '';

        switch( type ) {
            case 'textfield':
                templateUrl = 'components/form-field/textfield.html';
                break;
            case 'email':
                templateUrl = 'components/form-field/email.html';
                break;
            // etc...
        }

        return templateUrl;
    }

    var linker = function( scope, element ) {

        var templateUrl = getTemplateUrl( scope.field );
        $http.get(templateUrl).success(function(data) {
            element.html(data);
            $compile(element.contents())(scope);
        });
    }

    return {
        restrict: 'E',
        replace: true,
        scope: {
            field: '='
        },
        link: linker
    }
}]);

I understand the basics of directives and controllers, and the use of isolate scopes with regards to two-way data-binding and a module reuse perspective. So as I understand $compile and link, please correct me if I'm wrong:

So in the above example I'm creating and element directive, replace the directive markup in the DOM, attaching an isolate scope for reuse of the form fields, and attaching a linker function, which will be executed recursively invoked. It runs out and grabs my templateUrl based on my passed isolate scope and using injected $http. Then using a jQuery alias element with .html() and set the content to the returned template. The template is $compiled by by grabbing all the children and passing as param to compile. Which will return a link function, and then invokes the second link function with scope... correct?

Is this still the best way to implement dynamic templating? Most of the examples in Stackoverflow are similar, but all seem to be two years old, meaning they would be pre-AngularJS-1.2.

UPDATE The example provided below using ng-include by @user3677563 appears a much better implementation, from my junior angular eyes. What is the use case for the above code versus the ng-include example. Looking for pros/cons (ie. performance) and where I might implement something like the above snippet in the future. Also is my understanding of $compile and link correct?

Upvotes: 0

Views: 111

Answers (1)

johnrapp
johnrapp

Reputation: 46

For this i would recommend the ngInclude directive https://docs.angularjs.org/api/ng/directive/ngInclude

You simply create a ng-include element or add it as an attribute aswell as provide a source string attribute and it will automatically fetch and cache the html for you.

To implement this with your fieldproperty, you could add a getTemplateUrl function on your controller and provide it to the ngInclude directive.

Like so:

<ng-include url="getTemplateUrl(field)"></ng-include>

Upvotes: 1

Related Questions