Is there a way to add ng-class="whatever" into a directive or controller element with javascript?

8,794 views
Skip to first unread message

Lee Owen

unread,
Oct 28, 2012, 1:37:28 AM10/28/12
to ang...@googlegroups.com
Instead of declaring ng-class="myClasses" into a template, is there a way to add this via javascript, in the compile, or linking function?  Or any other way?

Thierry Chatel

unread,
Oct 28, 2012, 5:00:35 AM10/28/12
to ang...@googlegroups.com
In the compile function of a directive, it will work. You can use the compile function to modify the associated element and it's content, before the automatic compilation by Angular of that element.

In reality the 'compile' function should be seen as a pre-compile, or a preprocessor.

Witold Szczerba

unread,
Oct 28, 2012, 10:12:59 AM10/28/12
to ang...@googlegroups.com
Hi,
strange question, because in link or compile function, you have the
element right at your feet:
link: function(scope, element, ...) {
element.addClass('new-class');
element.removeClass('old-class');
element.hasClass('another-class');
element.find('li a').addClass('list-item-anchor-class');
//find more at: http://api.jquery.com/category/css/
}

Or did I misunderstand the question?

Regards,
Witold Szczerba
> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To post to this group, send email to ang...@googlegroups.com.
> To unsubscribe from this group, send email to
> angular+u...@googlegroups.com.
> Visit this group at http://groups.google.com/group/angular?hl=en.
>
>

Lee Owen

unread,
Oct 28, 2012, 1:16:19 PM10/28/12
to ang...@googlegroups.com
Yes, I can see how to manipulate the element, which is useful, I was just wondering if there was a way to programmatically set ngClass, instead of declaratively.

For example, I can add element.attr( 'ng-class', 'test' ) which adds the attribute to the element, but angular does not add the values of test to the element's class attribute as it would if I'd declared ng-class="test" in html.

Witold Szczerba

unread,
Oct 28, 2012, 2:45:30 PM10/28/12
to ang...@googlegroups.com
It is because you have to compile your markup if you want AngularJS to
execute it.
What is your use case?

Regards,
Witold Szczerba

Witold Szczerba

unread,
Oct 28, 2012, 3:00:23 PM10/28/12
to ang...@googlegroups.com
Hi,
are you sure, because I have tested it just yet and it looks like the
"compile" function is applied on a template which is already processed
by compiler (but before linker).
Can you double check it?

Regards,
Witold Szczerba

Thierry Chatel

unread,
Oct 28, 2012, 6:18:13 PM10/28/12
to ang...@googlegroups.com
Yes Witold, I'm sure that the compile() function is processed before compiling the whole element content, so you can modify the content, and even add directives to inner elements, that new content will be compiled, and the added directives will be executed. I just checked it again, it works.

But if we add new directives to the current element itself (and not an inner element), these added directives will not be executed. The compiler retrieves all the directives of an element, sort them by priority, then executes the compile() function of each of those directives. After that, it will compiles the content of the element, which may have been modified by some of those directives, but it won't see any added directive on the element itself.


So Lee, in your initial question, I didn't understand that you would add a ng-class directive on the current element itself. It's just the case that can't work. You can add a class attribute on the current element or any inner element, or a ng-class directive on any inner element, but not a ng-class directive on the current element.

Witold Szczerba

unread,
Oct 28, 2012, 7:06:57 PM10/28/12
to ang...@googlegroups.com
Thanks for checking it. Now it is all clear.

Regards,
Witold Szczerba

Lee Owen

unread,
Oct 28, 2012, 7:29:03 PM10/28/12
to ang...@googlegroups.com
I see, that is very helpful to know that it works for the element's contents.  Should it also work on the element itself, or is this working as intended?

dav...@gmail.com

unread,
Oct 29, 2012, 3:05:13 AM10/29/12
to ang...@googlegroups.com
You could replace the element itself with replace:true (and probably also transclude) and add the detectives to the replacement element. Still not sure why you want to do this. Is ng-class just a simplified example? You can just add classes yourself. If you're really aiming towards adding a more complicated custom directive, you'd be better off favoring out shared functionality into a Controller.

Thierry Chatel

unread,
Oct 29, 2012, 3:11:41 AM10/29/12
to ang...@googlegroups.com, dav...@gmail.com
He replaced the element, but even if the element is replaced, the directives on the replacing element are not executed.


Is it working as intended ? Well, being able to modify higher priority or same priority directives on the element itself would not be consistant. Imagine that you remove a same priority directive, it may or not have been already executed. Or if you add a higher priority directive, then executing it would break the priority order.

Which could be consistant, would be reloading lower priority directives after executing all directives of each priority level. I don't know if AngularJS developers thought about it, nor if it would be worth the extra process time.

Reply all
Reply to author
Forward
0 new messages