Skip to content

[5.X branch only] fix(common): don't recreate view when context shape doesn't change - #18277

Merged
vicb merged 1 commit into
angular:masterfrom
pkozlowski-opensource:template_outlet_context_recreate
Aug 7, 2017
Merged

vicb merged 1 commit into
angular:masterfrom
pkozlowski-opensource:template_outlet_context_recreate

Conversation

@pkozlowski-opensource

Copy link
Copy Markdown
Member

Fixes #13407

Problem description

When using ngTemplateOutlet with context as an object literal in a template and binding to the context's property the embedded view would get re-created even if context object remains essentially the same (the same shape, just update to one properties).

This happens since currently change detection will re-create object references when an object literal is used and one of its properties gets updated through a binding.

Solution proposal

This PR changes ngTemplateOutlet logic so we take contex't object shape into account before deciding if we should re-create view or just update existing context.

@pkozlowski-opensource pkozlowski-opensource added area: common Issues related to APIs in the @angular/common package action: review The PR is still awaiting reviews from at least one requested reviewer labels Jul 21, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

const

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ctxChange: SimpleChange is not correct (might be undefined)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

couldn't ctxChange be undefined here ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Nope, since the only way to get into this case would be to also change the templateRef. But this, in turn, would mean that we need to recreate view so wouldn't get into the else branch here.

In any case I've added a new test, just to be safe in the future (for example if we decide another @Input to the NgTemplateOutlet).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you please re-structure the code to improve clarity ?

  • add comments,
  • move ctxChange.isFirstChange() out of _hasContextShapeChanged so that the method actually does what it says (alternative is to rename the methods & add comments).

@pkozlowski-opensource
pkozlowski-opensource force-pushed the template_outlet_context_recreate branch from d5f1e98 to f0c578e Compare July 24, 2017 14:58

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

null should be undefined, right ?

@pkozlowski-opensource
pkozlowski-opensource force-pushed the template_outlet_context_recreate branch from f0c578e to 14713de Compare July 25, 2017 08:58
@pkozlowski-opensource

Copy link
Copy Markdown
Member Author

@vicb added comments, split code into smaller functions and simplified logic. Hopefully it is easier to follow now. PTAL

@vicb

vicb commented Jul 26, 2017

Copy link
Copy Markdown
Contributor

Change looks good but definitely a change in behavior. Should we merge in 4.x ?

@vicb vicb changed the title fix(common): don't recreate view when context shape doesn't change [5.X branch only] fix(common): don't recreate view when context shape doesn't change Jul 27, 2017
Problem description: when using ngTemplateOutlet with context as
an object literal in a template and binding to the context's property
the embedded view would get re-created even if context object remains
essentially the same (the same shape, just update to one properties).
This happens since currently change detection will re-create object
references when an object literal is used and one of its properties
gets updated through a binding.

Solution: this commit changes ngTemplateOutlet logic so we take
contex't object shape into account before deciding if we should
re-create view or just update existing context.

Fixes angular#13407
@pkozlowski-opensource
pkozlowski-opensource force-pushed the template_outlet_context_recreate branch from 14713de to 2871389 Compare August 7, 2017 18:16
@pkozlowski-opensource pkozlowski-opensource added the target: major This PR is targeted for the next major release label Aug 7, 2017
@vicb vicb added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Aug 7, 2017
@vicb
vicb merged commit 685cc26 into angular:master Aug 7, 2017
asnowwolf pushed a commit to asnowwolf/angular that referenced this pull request Aug 11, 2017
…ngular#18277)

Problem description: when using ngTemplateOutlet with context as
an object literal in a template and binding to the context's property
the embedded view would get re-created even if context object remains
essentially the same (the same shape, just update to one properties).
This happens since currently change detection will re-create object
references when an object literal is used and one of its properties
gets updated through a binding.

Solution: this commit changes ngTemplateOutlet logic so we take
context object shape into account before deciding if we should
re-create view or just update existing context.

Fixes angular#13407
juleskremer pushed a commit to juleskremer/angular that referenced this pull request Aug 26, 2017
…ngular#18277)

Problem description: when using ngTemplateOutlet with context as
an object literal in a template and binding to the context's property
the embedded view would get re-created even if context object remains
essentially the same (the same shape, just update to one properties).
This happens since currently change detection will re-create object
references when an object literal is used and one of its properties
gets updated through a binding.

Solution: this commit changes ngTemplateOutlet logic so we take
context object shape into account before deciding if we should
re-create view or just update existing context.

Fixes angular#13407
juleskremer pushed a commit to juleskremer/angular that referenced this pull request Aug 28, 2017
…ngular#18277)

Problem description: when using ngTemplateOutlet with context as
an object literal in a template and binding to the context's property
the embedded view would get re-created even if context object remains
essentially the same (the same shape, just update to one properties).
This happens since currently change detection will re-create object
references when an object literal is used and one of its properties
gets updated through a binding.

Solution: this commit changes ngTemplateOutlet logic so we take
context object shape into account before deciding if we should
re-create view or just update existing context.

Fixes angular#13407
@angular-automatic-lock-bot

Copy link
Copy Markdown

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 12, 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 area: common Issues related to APIs in the @angular/common package 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.

ngOutletContext causes template to re-initialize on data changes

3 participants