-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Directive with replace fails to merge its attributes with its template's attributes (e.g. ngClass, style etc) #5695
Comments
oh no don't credit me, what if it turns out to be a terrible idea! but it's something that we might be able to improve if people want it. To summarize, when merging the attributes from the compiled node into the template node, this can screw up ngClass or other directives expecting expressions. I'm not totally sure how to fix this (I don't think it would be a super trivial fix), but down the road it might be good to try |
Didn't mean it that way, sorry. BTW, here's how I'm solving it right now (fiddle):
It's hacky but it does the trick for now. |
Interesting issue, subscribing. |
I have a (failing) test case reproducing this issue but I wonder how to merge the attribute values in other cases. What would happen when you have a variable and an object? |
yeah, unfortunately this is not a super easy thing :( |
Ah, @caitp this touches on the issue I ran into earlier. Understood that it is complex but hopefully someone can implement a solution for this. |
@dariocravero Thanks for the quick fix suggestion. |
There's an additional complication here, which is that if the directive uses isolate scopes or scope inheritance, the Since replace is being deprecated, this probably isn't worth the trouble? |
it's not worth the trouble --- you can't really merge the ng-class attributes correctly, we can't special case certain attributes because it could apply to any attribute/directive that takes an expression --- there's basically no real fix, other than finding a way to link the ngClass directive twice for the same element. (and we can't really generalize that to other directives --- at least not without extending the directive API :() |
@teropa, can you clarify the comment about replace being deprecated? What should we be using instead? |
@KamBha right now you should be using |
Even if replace will be deprecated in the future, a solution (even temporary) would be really appreciated |
yeahhhhh this is supper annoying .... I'm running up against not being able to use ng-class on accordion right now. Any way we can fix this? |
@LeleDev you'll probably just need to make a custom directive for now that you use in a special case like this... that's what i did:
|
@btm1 : Thank you! I ended up using the class attribute at the moment: class="static-class-1 {{ condition1 ? 'dynamic-class-1' : '' }} {{ condition2 ? 'dynamic-class-2' : '' }}" Don't know which of the two workarounds is better (performance-wise) |
@LeleDev np ... I doubt there's much of a difference performance wise between the two: Both use a watch expression and are tied to the digest cycle so either way it's happen although with the class method each {{}} represents a separate watch expression, where as mine only uses one and evaluates each property in a supplied object just like ng-class. |
The same applies to |
Since a ngClass is already present in the uiSelect theme templates, we could not add any ngClass on <ui-select> without getting an JS error Currently, adding a ngClass on <ui-select> result in: `ng-class="{class: expression} {open: $select.open}"` With this fix, doing the same thing result in: `ng-class="{class: expression, open: $select.open}"` Closes angular-ui#277
I'm self-transcluding an element right now and this is quite interesting that I can't seamlessly merge both ng-classes the original and the one I need.... What is an ETA on this? |
Considering that:
I wouldn't hold my breath 😉 PRs are always welcome though, if someone feels brave 😁 |
|
If Because as stated, it's a totally neccesary construct. For elements that may not contain arbitrary/custom other elements, and for svg. |
@thany, depedning on the exact usecase, there might be different work-arounds/solutions available. |
The use-case is simple: I don't need those directive-element in my DOM because they mess up styling and they are not always allowed in places where they appear. On top of that, I like a clean DOM - a clean DOM is easy to understand for a CSS'er, provides a cleaner accesibility tree, and is easier to traverse in case when tracking down problems. So, what's the recommended thing to do instead of Actually, let's turn this question around: |
That is usually an issue with styling. Unfortunately, Bootstrap is notorious for tightly coupling its styling with DOM structure in some cases. Possible work-arounds:
Sound subjective (especially the first and last arguments). Having a
As mentioned above, I like these because they keep the resulting HTML much more declarative and structured (which is even more useful when troubleshooting). But besides that, a main reason for deprecating |
I'd expect a framework as well-maintained and well-proven to solve those problems, so I don't need to workaround stuff like this. I'm not using Bootstrap, or any other bloated CSS framework, but I do want sensible CSS. so things like
Never heard of that! It sounds fantastic, so why the 👎?
That's a shortcoming of Angular in general then: it parses the templates after the browser has seen them. Iow, it relies on the browser to parse templates, which is why Angular cannot divergence from html syntax too much, and this is why we need strange workarounds like ng-attr-* in some cases. It's also the reason why I guess this is where React shines. But React has too many other shortcomings for me ;)
That's also subjective. So we have differing opinions. That's ok. I can see your points, hopefully you can see mine. |
¯_(ツ)_/¯
It is generally considered a good practice to prefer tag name or attribute directives over comment and class names, as it makes it easier to determine what directives a given element matches. Also, avoid comment and class name directives allows you to turn on some optimization in
True - nobody said Angular 1 is perfect 😃
Exactly! I was just pointing out the subjectiveness 😃 |
Say I have the a directive called
myDirective
which has the following template:Say I want to add more conditions to
ng-class
:The expected result would be:
However, Angular is producing this:
Which of course causes an error since it isn't a valid expression.
My question is: should a directive that has an
ng-class
attribute merge it with whatever the caller send on itsng-class
attribute?I asked on IRC and @caitp suggested it might be an issue on the way Expressions are resolved and that I should wrote this issue.
Thanks! :)
The text was updated successfully, but these errors were encountered: