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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

TemplateRef passed into other component not checked under Ivy #33393

Closed
vthinkxie opened this issue Oct 25, 2019 · 6 comments

Comments

@vthinkxie
Copy link
Contributor

@vthinkxie vthinkxie commented Oct 25, 2019

馃悶 bug report

Affected Package

angular 9 with ivy

Is this a regression?

yes

Description

I check the Ivy Minor Change docs here

https://docs.google.com/document/d/1Dije0AsJ0PxL3NaeNPxpYDeapj30b_QC0xfeIvIIzgg/preview

and found that

If a template is declared in one view but inserted into a different view, change detection will occur for that template only when its insertion point is checked (previously, change detection would also run when its declaration point was checked).

It will bring lots of break changes to our UI library when upgrading it to angular 9 with ivy, because of many components' input support both string and TemplateRef<any> type, and all components are working under OnPush mode.

When the user passes a TemplateRef with a variable to the component, the template inside the component won't update any longer even if the variable has changed outside the component, which is a very common situation.

For example

the select API here: https://ng.ant.design/components/select/en#api

Property Description Type Default
[nzNotFoundContent] Specify content to show when no result matches.. string | TemplateRef<void> 'Not Found'

The feature comes from a directive here: https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/components/core/addon/string_template_outlet.ts#L24 which brought a lot of convenience to the user.

I wonder if it is possible to keep the same as the previous version of the template check behavior

Thanks a lot

馃敩 Minimal Reproduction

it works with angular 8 in the stackblitz, but not work under 9.0.0-next

https://stackblitz.com/edit/angular-99qln5?file=src/app/hello.component.ts

I could not enable ivy in stackblitz, so there is no online repro here.
Download and upgrade all @angular/*, you can find the name inside the component is Angular, but the outside name is Angular Next after 3 sec.

馃敟 Exception or Error

馃實 Your Environment

Angular Version:


@angular-devkit/architect         0.900.0-next.15
@angular-devkit/build-angular     0.900.0-next.15
@angular-devkit/build-optimizer   0.900.0-next.15
@angular-devkit/build-webpack     0.900.0-next.15
@angular-devkit/core              9.0.0-next.15
@angular-devkit/schematics        9.0.0-next.15
@angular/cli                      9.0.0-next.15
@ngtools/webpack                  9.0.0-next.15
@schematics/angular               9.0.0-next.15
@schematics/update                0.900.0-next.15
rxjs                              6.5.3
typescript                        3.6.4
webpack                           4.41.2


@pshurygin

This comment has been minimized.

Copy link

@pshurygin pshurygin commented Oct 25, 2019

I agree that this is a very confusing change. The problem here is when using OnPush, how would the insertion point component know if some bindings were changed in the external template, and mark itself for check?

I can see that angular material is facing the same issue and they workaround it by disabling OnPush, which is not really a great thing to do as far as i'm concerned. Our angular app is actually using OnPush on every component, but now it looks it would not be possible to follow this strategy anymore.

The previous behavior looks absolutely logical to me (check template when either insertion point or the origin view is checked).

Also, i would argue that this is a "less common" breaking change, as passing TemplateRefs around the app is a pretty common strategy for angular apps of medium to large scale.

@vthinkxie vthinkxie changed the title TemplateRef passed into other component not checked TemplateRef passed into other component not checked under Ivy Oct 25, 2019
@trotyl

This comment has been minimized.

Copy link
Contributor

@trotyl trotyl commented Oct 25, 2019

Relates to #33285

@ngbot ngbot bot modified the milestone: needsTriage Oct 25, 2019
@manklu

This comment has been minimized.

Copy link

@manklu manklu commented Oct 25, 2019

@vthinkxie Instead of manually trigger change detection, you could use rxjs.
See #33285 (comment) for a sample

@vthinkxie

This comment has been minimized.

Copy link
Contributor Author

@vthinkxie vthinkxie commented Oct 26, 2019

@manklu there are a lot of ways to make it work, but the point is the breaking change, we can not count on all lib users to modify all the variables to async observable, it brings too many troubles to them.

@IgorMinar

This comment has been minimized.

Copy link
Member

@IgorMinar IgorMinar commented Oct 31, 2019

We are looking into this issue, and reconsidering if this incompatibility is justified. It does appear that this is something we need to fix.

@jbedard

This comment has been minimized.

Copy link
Contributor

@jbedard jbedard commented Nov 3, 2019

I've run into this in multiple places now. This does seem odd imo. I would almost expect the opposite behavior of what ivy is doing. Data frequently comes from the template definition/declaration location...

@IgorMinar IgorMinar modified the milestones: Backlog, v9-blockers Nov 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can鈥檛 perform that action at this time.