0

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:

  • ng-app creates a $rootScope, and begins compiling DOMElements, which consists of compiling and linking
  • $compile traverse DOMElements (apparently differently than other frameworks???)
  • $compile is looking for directives, which when found are pushed onto a list for sorting and execution of their compile functions
  • $compile returns a linking function... which is then made into another linking function and returned and executed
  • linker passes the required scope for binding on, and recursively executes child link functions
  • linker returns a set of data bound DOMElements with attached listeners for interactivity, and is finally appended to parent node

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?

1 Answer 1

1

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>
Sign up to request clarification or add additional context in comments.

1 Comment

Hi, that's great. Works like a charm. What would the use case be for the snippet I have above then? And do I have the idea behind $compile, link functions, and the code worked out right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.