Skip to content
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

feat(ivy): support injecting ChangeDetectorRef #22469

Closed
wants to merge 2 commits into from
Closed

Conversation

kara
Copy link
Contributor

@kara kara commented Feb 27, 2018

This PR adds basic support for injecting the correct ChangeDetectorRef. This will pave the way for supporting and testing ChangeDetectorRef's various methods, but this PR does not add any of those methods.

Notes:

  • In current Angular, when you inject a ChangeDetectorRef, what you get in practice is a ViewRef (which implements EmbeddedViewRef). I've preserved that for backwards compatibility.
  • There were two conflicting EmbeddedViewRef implementations in render3: one in di.ts and one in component.ts. I've deleted both and combined their logic in a new file (view_ref.ts). The detectChanges arg has been removed until it can be properly supported/tested in a follow-up PR.
  • When injecting a component's ChangeDetectorRef, the context cannot be set at creation time because the context is the component instance itself (circular dependency). In this implementation, the context is set in elementStart after the component instance is created.
    • An alternative could be to set the context immediately after instantiation in the component factory function, but I ended up avoiding that route because it a) would probably need a special case in the compiler and b) would generate more code for apps injecting ChangeDetectorRef 2+ times.

TODO in follow-up PRs:

  • Implement detectChanges and markForCheck
  • containingDirty flag and associated function
  • Support attaching and detaching change detector refs

@mary-poppins
Copy link

You can preview 4b79e33 at https://pr22469-4b79e33.ngbuilds.io/.

@mary-poppins
Copy link

You can preview bc2e407 at https://pr22469-bc2e407.ngbuilds.io/.

@mary-poppins
Copy link

You can preview 8849439 at https://pr22469-8849439.ngbuilds.io/.

@mary-poppins
Copy link

You can preview f40ca1e at https://pr22469-f40ca1e.ngbuilds.io/.

@kara kara requested a review from mhevery February 27, 2018 16:02
@kara kara added action: review The PR is still awaiting reviews from at least one requested reviewer and removed state: WIP labels Feb 27, 2018
Copy link
Contributor

@mhevery mhevery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor fixes.

return di.changeDetectorRef = getOrCreateHostChangeDetector(currentNode.view.node);
} else if ((currentNode.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Element) {
// if it's an element node with data, it's a component and context will be set later
return di.changeDetectorRef = createViewRef(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we call createViewRef(null) because we don't have the instance just yet, that makes sense. But what if someone does injector.get(ViewRef)? in that case I assume we would call getOrCreateChangeDetectorRef and we would incorrectly create a ViewRef with null. I think we should have getOrCreateChangeDetectorRef take the context in the args. Then injectChangeDetectorRefcan invokegetOrCreateChangeDetectorRefwithnullandinjector.get(ViewRef)can invoke it with correctcontext`.

@@ -580,9 +590,9 @@ export function locateHostElement(
* @param rNode Render host element.
* @param def ComponentDef
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add @returns documentation

/** Sets the context for a ChangeDetectorRef to the given instance. */
export function initChangeDetectorIfExisting(injector: LInjector | null, instance: any): void {
if (injector && injector.changeDetectorRef != null) {
(injector.changeDetectorRef as any)._setComponentContext(instance);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

injector.changeDetectorRef as ViewRef<any> would be better.

it('should inject host component ChangeDetectorRef into directives on containers', () => {
class IfDirective {
/* @Input */
if
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-format thinks that if is a keyword here and it messes up. Can you come up with a name which is not a keyword? MyIfDirictive => myIf?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doh! How did I miss that.

@kara
Copy link
Contributor Author

kara commented Feb 28, 2018

presubmit

@kara kara added the target: major This PR is targeted for the next major release label Feb 28, 2018
@mary-poppins
Copy link

You can preview 48fd28f at https://pr22469-48fd28f.ngbuilds.io/.

@mhevery mhevery removed the action: review The PR is still awaiting reviews from at least one requested reviewer label Feb 28, 2018
@ngbot
Copy link

ngbot bot commented Feb 28, 2018

Hi @kara! This PR has merge conflicts due to recent upstream merges.
Please help to unblock it by resolving these conflicts. Thanks!

@mary-poppins
Copy link

You can preview c2c58ac at https://pr22469-c2c58ac.ngbuilds.io/.

@kara kara added the action: merge The PR is ready for merge by the caretaker label Feb 28, 2018
@alexeagle alexeagle closed this in 9eaf1bb Feb 28, 2018
leo6104 pushed a commit to leo6104/angular that referenced this pull request Mar 25, 2018
@kara kara deleted the cdr branch October 13, 2018 01:09
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants