Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to write a directive for angularjs that replaces the dom element but keeps bindings

following on from this question: how to write a directive for angularjs that replaces dom elements without using ng-transclude?

I wish to write a directive that changes the dom element but then retains all the attributes and bindings.

<g:text x={{myX}} y={{myY}} font-size=10>Hello There</g:text>

to

<text x={{myX}} y={{myY}} font-size=10>Hello There</text>

thanks in advance!

like image 797
zcaudate Avatar asked Dec 14 '12 12:12

zcaudate


People also ask

What are AngularJS directives?

What are Directives? At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler($compile) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.

How to change the style of DOM elements in angular?

We can use attribute directives to change the style of DOM elements. These directives are also used to hide or show particular DOM elements conditionally. Angular provides many built-in Attribute Directives like NgStyle, NgClass, etc. We can also create our own custom Attribute Directives for our desired functionality.

How can a programmer use Dom in AngularJS?

A programmer can use DOM in AngularJS for the following purposes: 1 Documents are built using DOM elements. 2 A Programmer can navigate documents structure with DOM elements. 3 A programmer can add elements and content with DOM elements. 4 Programmer can modify elements and content with DOM elements. More ...

What is the use of restrict e in angular?

The restrict:'E' is required by angular to ensure that the data from the inner directive is available to the outer directive. The letter 'E' is the short form of the word 'Element'.


2 Answers

To the best of my knowledge, Angular will port attributes to the new element automatically. No need to iterate over them all yourself.

In your case, you would also need to transclude the content if you want to keep it.

app.directive('myText', function() {
    return {
        replace: true,
        template: '<text ng-transclude></text>'
    }
});

This is from the top of my memory, but I believe something similar to this would do the trick. Every attribute of the original element will be ported to the new element, and the element's content will be transcluded too. Binds preserved and all.

like image 106
diegovilar Avatar answered Sep 28 '22 07:09

diegovilar


Use the same logic and copy the attributes during the compile:

 app.directive('gText', function() {
    return {
        restrict: 'E',
        compile: function(tElement, tAttrs) {
            var attrs = tElement[0].attributes;
            tElement.replaceWith('<text>' + tElement.text() + '</text>');            
            for (var i=0; i < attrs.length; i++) {
                tElement.attr(attrs.item(i).nodeName, attrs.item(i).nodeValue);               
            }
        }
    }
});

fiddle: http://jsfiddle.net/YWfSF/

like image 25
bmleite Avatar answered Sep 28 '22 06:09

bmleite