Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS directive that uses the original element type in template

I'm developing UI and typography based directives for Angular. In such cases, the element the directive is being applied on is unknown - anything from a div, span, h1 to an h5.

The reason for using a template is so I can add ng-* directives to it (so the developer doesn't need to remember anything but the directive name).

I've had limited success adding attributes and recompiling the element. No success when it comes to adding ng-transclude however. Creating a new element and replacing the old comes with integration issues (ignore other directives and data attributes that may be on the element), had little success copying these attributes and adding them to the new element.

This seems like it should be really simple, as template itself can change the element to whatever you specify (using transclude and replace), surely there's the 'long way of doing it'?

It's too bad you can't do the following:

module.directive( 'myDir', [ '$window', function( $window ) {
    return {
        restrict: "A",
        controller: function( $scope, $element ) {
            $scope.tag = $element[0].nodeName;
        }
        template: "<{{tag}} data-ng-transclude ng-*=''></{{tag}}>",
        transclude: true,
        replace: true,
        link: function ( scope, element, attrs ) {

        }
    }   
}]);

I think the major issue is I'm looking to replace and transclude the element with the template, not add the template (or compile the element) as a child.

I have since replaced the need for ng-* and templates with vanilla JS in my code, eg:

<div data-ng-style="{'font-size':fontSize}></div>

with

element[0].style.fontSize = scope.fontSize;

Which begs the question of the benefit of using many ng-* directives? Is it just 'the Angular way'?

like image 585
Patrick Avatar asked Nov 22 '13 05:11

Patrick


People also ask

What are the directives of AngularJS?

AngularJS directives are extended HTML attributes with the prefix ng- . The ng-app directive initializes an AngularJS application. The ng-init directive initializes application data. The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.

Which directive is used for data binding in AngularJS?

A - ng-bind directive binds the AngularJS Application data to HTML tags.

Which of the directive is used to display text in AngularJS?

ng-app: The ng-app Directive in AngularJS is used to define the root element of an AngularJS application. This directive automatically initializes the AngularJS application on page load. It can be used to load various modules in AngularJS Application.

How many types of directives are there in AngularJS?

There are two types of AngularJs directives: Built-in directive.


1 Answers

I've been mulling over this question for a couple weeks now until I realised that template could be a function with the ability to access element and attrs. Thus I was able to return a template with the existing element tags.

module.directive( 'myDir', [ '$window', function( $window ) {
    return {
        restrict: "A",
        template: function( element, attrs ) {
            var tag = element[0].nodeName;
            return "<"+tag+" data-ng-transclude ng-*=''></"+tag+">";
        },
        transclude: true,
        replace: true,
        link: function ( scope, element, attrs ) {

        }
    }   
}]);

HTML

<div data-my-dir>
    <span>some other stuff</span>
    <div>more stuff</div>
</div>

<span data-my-dir></span>

<h1 data-my-dir></h1>

Output

<div ng-*="" data-ng-transclude="" data-my-dir="">
    <span class="ng-scope">some other stuff</span>
    <div class="ng-scope">more stuff</div>
</div>

<span ng-*="" data-ng-transclude="" data-my-dir=""></span>

<h1 ng-*="" data-ng-transclude="" data-my-dir=""></h1>
like image 132
Patrick Avatar answered Oct 23 '22 12:10

Patrick