This repository was archived by the owner on Apr 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27.4k
ngClass[Odd/Even] overhaul #15228
Closed
+399
−128
Closed
ngClass[Odd/Even] overhaul #15228
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
8822006
refactor(ngClass): remove unnecessary dependency on `$animate`
gkalpak 0409589
refactor(ngClass): remove redundant `$observe`r
gkalpak 2705085
test(ngClass): add some tests about one-time bindings and objects ins…
gkalpak 0ba4be6
fix(ngClassOdd/Even): keep track of classes even if odd/even do not m…
gkalpak 89268af
perf(ngClass): only access the element's `data` once
gkalpak 2871a11
refactor(ngClass): simplify conditions
gkalpak a7e69f7
refactor(ngClass): move helper functions outside the closure
gkalpak 37cec7a
refactor(ngClass): exit `arrayDifference()` early if an input is empty
gkalpak 5708424
perf(ngClass): avoid deep-watching (if possible) and unnecessary copies
gkalpak 739f723
fixup! refactor(ngClass): remove unnecessary dependency on `$animate`
gkalpak 181c51b
fixup! refactor(ngClass): remove redundant `$observe`r
gkalpak 16e666b
fixup! test(ngClass): add some tests about one-time bindings and obje…
gkalpak dfe4307
squash! fix(ngClassOdd/Even): keep track of classes even if odd/even …
gkalpak f766698
fixup! perf(ngClass): avoid deep-watching (if possible) and unnecessa…
gkalpak a9742f9
fixup! refactor(ngClass): simplify conditions
gkalpak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This description makes hard to understand what is actually being tested.
Are you saying that ngClass is not removing old classes when both the $index and the expression value changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be because I was trying to solve it differently at first. Here is what was happening before this change:
ng-class-odd="foo"
,$index = 0
,foo = 'foo'
. The element hasclassName === 'foo'
.$index
andfoo
change simultaneously, say$index = 1
,foo = 'bar'
, then:attr[name]
watch kicks in first and it checks ifscope.$index & 1 === selector
(i.e. it uses the current value of$index
to determine if it needs to update the classes). It decides it doesn't need to do anything, so at this point the element still hasclassName === 'foo'
.$index
watch kicks in. Since it determines that$index & 1 !== old$index & 1
, it decides to remove the classes. But it tries toscope.$eval(attr[name])
which now evaluates to'bar'
. So the element will still haveclassName === 'foo'
.Basically, the problem is that both watch-actions check against the current value of each other to determine what to do, which fails when both change in the same digest.
I.e. the
attr[name]
watch usesscope.$index
(while it should use the previous index) and the$index
watch usesscope.$eval(attr[name])
(while it should use the previous value - the "old classes").The commit fxes it by:
$index
watch before theattr[name]
watch.oldVal
from the$index
watch to add/remove.This way, when the
$index & 1
changes, the$index
watch will correctly add/remove the classes and then theattr[name]
watch will update the classes (i.e. add the new ones) if necessary.I hope this makes sense 😃
How about: