Repository navigation
fix(ivy): take components into account when discovering directives #26113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,10 +95,11 @@ export function getInjector(target: {}): Injector|null { | |
| } | ||
|
|
||
| /** | ||
| * Returns a list of all the directives that are associated | ||
| * with the underlying target element. | ||
| * Returns a list of all the directives that are associated with the underlying target element. | ||
| * Accepts an optional argument to indicate if component instances should be returned as well (false | ||
| * by default). | ||
| */ | ||
| export function getDirectives(target: {}): Array<{}> { | ||
| export function getDirectives(target: {}, includeComponents?: boolean): Array<{}> { | ||
| const context = loadContext(target) !; | ||
|
|
||
| if (context.directives === undefined) { | ||
|
|
@@ -108,7 +109,14 @@ export function getDirectives(target: {}): Array<{}> { | |
| null; | ||
| } | ||
|
|
||
| return context.directives || []; | ||
| const result = context.directives || []; | ||
|
|
||
| // discard first directive if it is a component and we should not include components | ||
| if (!includeComponents && result.length && isComponentInstance(result[0])) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. I think we can just check the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I don't think we've got access to TNode at this point any more...
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can look it up using
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kara see alternative proposal in https://github.com/angular/angular/pull/26113/files#r221942800 If we could store directives start index, no of directives we could easily just slice WDYT? |
||
| return result.slice(1); | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| function loadContext(target: {}): LContext { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
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.
I'm not sure I understand why we still need to generate an array of indices when we could just slice from the directives array directly to retrieve the instances?
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.
@kara I think I might know where the confusion is coming from - you comment seems to imply that the
discoverDirectiveIndicesis used only to get directive instances but the way I understood the existing code is thatdiscoverDirectiveIndicesanddiscoverDirectivesare 2 independent functions that could, but don't have to be used together.In fact for the TestBed implementation I don't care about directive instances but need to get directive definitions. For this case the
discoverDirectiveIndicescomes handy and in this particular case I just don't want to slice LViewData to get directive instances as I don't care about instances.In the similar spirit I've interpreted
discoverDirectivesas a utility function that can take any set of indices (not all directives present on a node need to be present in this set) in any particular order. Maybe this wasn't the intention of those 2 functions.Having said all this I very much dislike the fact that we've got both directive indices and directive instances on LContext as those things can easily get out of sync.
Maybe a better approach would be to store sth like
directvesStartIndexanddirectivesCountand have higher-level utility functions working on those 2 pieces of data? If we store the above:WDYT?
Uh oh!
There was an error while loading. Please reload this page.
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.
If you need the defs in
TestBedand don't want to look up theTNode, I'd prefer storing the start index/count or theTNodeitself (which contains the start index/count) inLContext. Otherwise we are unnecessarily allocating an extra array in memory, as well as looping over the directives array twice for no good reason.IIRC, the original intent of
discoverDirectiveIndiceswas simply to grab non-component directive indices when we couldn't assume the component would be first in the list. I don't think it's particularly useful externally, so I think we should get rid of it anddiscoverDirectives/TestBedshould use start/end indices to slice what they need directly.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.
OK, so based on your comment it seems to me like I'm trying to re-purpose the
discoverDirectives/discoverDirectiveIndicesin the way that is different from the initial / intended design. As such I think that I will just add the needed code to the TestBed impl (I've got access to TNode).I'm going to close this PR for now. In the future, if there is some code that can be shared / refactored I will pull it into LContext. Thnx for taking time to review and bearing with me!