-
Notifications
You must be signed in to change notification settings - Fork 27.4k
NgClass is not evaluating array expressions #15905
Comments
I've updated your plunkr and it's working fine: http://plnkr.co/edit/XIgL7uFKGFXOM06111Ir?p=preview The reason why you're plunkr is not working is because To demonstrate this, I updated your original plunkr once again (this time only using a minimal change to show you it's working, just not updating) to set a default style: You can see that the initial style gets applied perfect, however changes are not getting reflected in the UI because the array never changes. |
Thank you for your explanation. I understand what's happening. So the behavior on Angular <1.6.4 is actually unexpected? I was under the impression that each digest cycle would check all expressions even if the object was the same. |
As angular.js/src/ng/directive/ngClass.js Line 39 in d0622d0
$watchGroup (see: https://docs.angularjs.org/api/ng/type/$rootScope.Scope ).
The question remains whether or not this is something that should be covered. |
For me this was quite a breaking change when I upgraded to 1.6.4. |
I quickly tested a few Angular versions. It works with 1.5.4 and higher until 1.6.3. |
Hm, this is an effect of the refactoring / fix Jason did.
It only talks about the expression as such, not about deep watching. There were also no tests for this, so we didn't purposefully change this. At the moment, I think this is expected behavior. |
@Narretz The commit also states:
It looks like it was intended to change the behavior? |
Yes and no ;). What I meant was that we intended to remove deepEquals, but didn't intend to break this behavior, because it was never supported explicitly in the first place (no tests, no clear docs, and afact Jason didn't know that this might be use case). |
@GiDW thanks for finding this commit. It really looks like for 1.5.5 to 1.6.3 this was an unsupported feature. |
The test for f975d8d still passes (unless it was deleted?). I think my change only effected one-time which was previously deep watched due to a now fixed bug. Is this issue only with one-time? (On mobile so it's a little hard to check the plunkr) |
I'm also experiencing this trying to use a filter to determine whether a validation class should be shown. An example is:
where http://plnkr.co/edit/oVpXjI6RwwN3WN19dPb7?p=preview I suppose I could figure out another solution but it doesn't seem to be as clean. I'm open to suggestions. I figured I'd comment since this also seems to be affecting the object syntax of |
Hmm, that expression should still work. Maybe the use of interceptors changes the normal literal watching? |
That's correct. The difference is that the test uses a variable in the expression It's also definitely caused by 60394a9 @OzzieOrca example is special again because it's using a filter in the object value (but also a literal in the ngClass expression). |
I think the origin of the issue is this line: 60394a9#diff-780de070ede30180f6aedb6c5f7d57caR1921 When adding the interceptor, we now mark the regularInterceptedExpression as literal. Previously, when adding the interceptor this information was lost. And being literal obviously changes the change detection ... although I'm not sure about the details. (The thing is that an expression like |
I thought marking it as a literal would handle this exact problem. Maybe that was wrong? |
by marking the toClassString interceptorFn as $stateful Fixes angular#15905
by no longer marking interceptorFn wrapped literals as literal Fixes angular#15905
by no longer marking interceptorFn wrapped literals as literal Fixes angular#15905
I'm not too sure what to do here... I've been trying to remove some of the issues with literals vs non-literals lately so code outside parse.js doesn't have to workaround these. Previously literals often forced the use of This specific issue was caused by 60394a9#diff-780de070ede30180f6aedb6c5f7d57caR1921 which took advantage of the literal watching enabled by 25f008f#diff-780de070ede30180f6aedb6c5f7d57caR1791 A few solutions:
Opinions? Other ideas? |
Also note that I think interceptors and filters should be treated the same, or at least very similar. Today they are treated the same for inputs/$stateful. 60394a9 added propagation of the literal flag onto the interceptor, maybe the same should be done for filters as well? That might (partially) fix #15874 as well. |
This would affect all expressions. So does something like
Sounds technically good, but does it impact performance? Or would there a measurable difference between before- 60394a9 , 60394a9 , and with $stateful? |
I meant only removing support in I would be worried about marking |
I'm leaning toward a breaking change to remove the support for nested array/objects in This will align it more with Angular ngClass (based on my 2 minutes of looking at the class and playing on plnkr, please correct me if I'm wrong). Then |
This has been fixed in both 1.6 and 1.7 without any breaking changes to 7084dec + 189461f caused some expression-inputs to only be shallow watched (= good!). But in some cases that is not enough (= bugs).
b5118ac fixed the filter/+/other cases |
I'm submitting a ...
Current behavior:
When using ng-class with an expression that evaluates to an array, the classes are not added.
Expected / new behavior:
The classes defined in the objects of the array should be applied to the DOM element when their expression is true.
Basically the third way in which the ng-class directive operates as explained in the docs.
Minimal reproduction of the problem with instructions:
Toggle 1 should change the background color of both boxes.
This works in Angular 1.6.3 but it stops working with Angular 1.6.4.
By changing the angular version number you can see the different behavior.
http://plnkr.co/edit/GARSFyXFLKA00oa4Julz
Angular version: 1.6.4
Browser: [all]
The text was updated successfully, but these errors were encountered: