Skip to content

ng-template not working in angular 9 with IVY #36238

Closed

Description

@kumaresan-subramani

🐞 bug report

ng-template is not working properly in angular 9 but working fine in angular 8

Is this a regression?

yes, working fine in angular 8

Description

I have created same application in both angular 8 and angular 9, my application working fine in angular 8.

🔬 Minimal Reproduction

Working sample

  1. download below angular 8 sample
    angular8.zip

  2. Give "npm i" and "ng serve"

3.then chose any one row from grid and click "edit" button, you wiill see below

image

my template working fine.

issue sample

  1. download below angular 9 sample

angular 9.zip

  1. Give "npm i" and "ng serve"

3.then below screen occurs , then chose any one row from grid and click "edit" button, you wiill see below

image

Code snippet

<ejs-grid [dataSource]='data' allowPaging='true' [pageSettings]='pageSettings' [editSettings]='editSettings' [toolbar]='toolbar' (actionBegin)='actionBegin($event)' (actionComplete)='actionComplete($event)'>
      <e-columns>
          <e-column field='OrderID' headerText='Order ID' width='120' textAlign='Right' [isPrimaryKey]='true'></e-column>
          <e-column field='CustomerName' headerText='Customer Name' width='120'></e-column>
          <e-column field='Freight' headerText='Freight' width='120' format='C2' textAlign='Right'></e-column>
          <e-column field='OrderDate' headerText='Order Date' width='130' format='yMd' textAlign='Right'></e-column>
          <e-column field='ShipCountry' headerText='Ship Country' width='150'></e-column>
      </e-columns>
      <ng-template #editSettingsTemplate let-data>
          <div ngForm #orderForm="ngForm">
              <table class="e-table e-inline-edit" cellspacing="0.25">
                  <colgroup>`
                          <col style="width: 120px;">
                          <col style="width: 120px;">
                          <col style="width: 120px;">
                          <col style="width: 130px;">
                          <col style="width: 150px;">
                  </colgroup>
                  <tbody>
                      <tr>
                          <td style="text-align: right" class='e-rowcell'>
                              <div class="e-input-group" [ngClass]= "{'e-disabled': !data.isAdd}">
                                  <input class="e-input e-field" [(ngModel)]="orderData.OrderID" required [attr.disabled]="!data.isAdd ? '' : null" name='OrderID' type="text" (focus)="focusIn($event.target)"
                                      (blur)="focusOut($event.target)" #OrderID style="text-align: right"  />
                              </div>
                          </td>
                          <td class='e-rowcell'>
                              <div class="e-input-group">
                                  <input class="e-input e-field" name='CustomerName' [(ngModel)]="orderData.CustomerName" required type="text" (focus)="focusIn($event.target)"
                                      (blur)="focusOut($event.target)" #CustomerName />
                              </div>
                          </td>
                          <td style="text-align: right" class='e-rowcell'>
                              <ejs-numerictextbox name="Freight" id="Freight" [(ngModel)]="orderData.Freight" floatLabelType='Never'></ejs-numerictextbox>
                          </td>
                          <td style="text-align: right" class='e-rowcell'>
                              <ejs-datepicker id="OrderDate" name="OrderDate" required [(ngModel)]="orderData.OrderDate" floatLabelType='Never'></ejs-datepicker>                            
                          </td>
                          <td class='e-rowcell'>
                              <ejs-dropdownlist id="ShipCountry" name="ShipCountry" [(ngModel)]="orderData.ShipCountry" [dataSource]='shipCountryDistinctData' [fields]="{text: 'ShipCountry', value: 'ShipCountry' }" popupHeight='300px' floatLabelType='Never'></ejs-dropdownlist>
                          </td>
                      </tr>
                  </tbody>
              </table>
          </div>
      </ng-template>
  </ejs-grid>

🌍 Your Environment

Angular Version:


"@angular/animations": "~9.0.2",
    "@angular/common": "~9.0.2",
    "@angular/compiler": "~9.0.2",
    "@angular/core": "~9.0.2",
    "@angular/forms": "~9.0.2",
    "@angular/platform-browser": "~9.0.2",
    "@angular/platform-browser-dynamic": "~9.0.2",
    "@angular/router": "~9.0.2",
"@angular-devkit/build-angular": "~0.900.3",
    "@angular/cli": "~9.0.3",
    "@angular/compiler-cli": "~9.0.2",
    "@angular/language-service": "~9.0.2",

Anything else relevant?
Both angular 8 and angular 9, my template reference are same in my soure level"ngAfterContnctChecked" hook.

angular 8 reference:

image

angular 9 reference:

image

Activity

  1. JoostK commented on Mar 25, 2020

    @JoostK
    Member

    In the Angular 8 screenshot, the ngAfterContentChecked is called with a ComponentBase instance as first parameter. This is not part of the signature of this method according to the AfterContentChecked interface, and it's not provided as such by Angular itself. I suspect that your decorators inject custom behaviour into how hooks are called, which had to be reworked because of #31495 which has broken this setup. The stack trace is missing in the Angular 8 screenshot so I can't know for sure, but there's likely an additional stack frame in the Angular 8 case.

  2. kumaresan-subramani commented on Mar 25, 2020

    @kumaresan-subramani
    Author

    HI @JoostK ,

    We have used custom decarators to over-ride my angular componet hooks, it works tll anglar 9.

    but in anglar 9 with IVY, it does not work due to this issue so that we have created new instance of my class which has all life cycle hook functionalities like below:

    https://github.com/syncfusion/ej2-angular-ui-components/blob/master/components/grids/src/grid/grid.component.ts#L233

    ans then i have passed current instace to newly created class instance which has all lie cycle hook functionalities like below

    https://github.com/syncfusion/ej2-angular-ui-components/blob/master/components/grids/src/grid/grid.component.ts#L237

    My issue is ng-template compilation not working fine in angular 9 but template reference are same i both angular 8 and 9

    working fine in angular 8

    not working in angular 9

  3. kumaresan-subramani commented on Mar 25, 2020

    @kumaresan-subramani
    Author
  4. kumaresan-subramani commented on Mar 26, 2020

    @kumaresan-subramani
    Author
  5. alxhub commented on Mar 27, 2020

    @alxhub
    Member

    One of the Ivy compatibility "changes you may see" on https://angular.io/guide/ivy-compatibility is:

    It's no longer possible to overwrite lifecycle hooks with mocks on directive instances for testing (instead, modify the lifecycle hook on the directive type itself).

    This is a performance optimization - reading a function from an arbitrary component is expensive, and so Angular only does it once from the component's prototype.

    Unfortunately you'll need to rework your decorator logic to not rely on arbitrary overwriting of lifecycle hooks.

  6. kumaresan-subramani commented on Mar 27, 2020

    @kumaresan-subramani
    Author
  7. kumaresan-subramani commented on Mar 30, 2020

    @kumaresan-subramani
    Author

    HI @alxhub ,

    I think you misunderstood my problem.

    i found root cause, which is when i select anyone row and then click edit button, it triggers my component's [which is placed inside ng-template] life cycle hook in angular 8 so that component which has been placed inside ng-template get rendered properly

    But in angular9, when i click edit button it doesn't trigger my life cycle hooks properly. so that ng-template not working

    when i click "edit" button,
    image

    it triggers, my life cycle hook from angular core level like below image

    image

  8. Achilles1515 commented on Mar 31, 2020

    @Achilles1515

    It's no longer possible to overwrite lifecycle hooks with mocks on directive instances for testing (instead, modify the lifecycle hook on the directive type itself).

    @alxhub But this will be changing "soon"...right?
    #35464

  9. bryanrideshark commented on Mar 31, 2020

    @bryanrideshark

    @alxhub , we're going to be merging #35464 and making it possible to override the prototype before startup right? It'll still be pretty efficient AFAIK, because the read will be cached once the first component of that type has been instantiated.

    I think a lot of more advanced users of Angular are waiting with eager expectation for #35464 to be merged.

  10. alxhub commented on Mar 31, 2020

    @alxhub
    Member

    @bryanrideshark that'd be a better question for @kara, I don't work on the core specifically. But that approach looks sound to me.

  11. angular-automatic-lock-bot commented on May 1, 2020

    @angular-automatic-lock-bot

    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.

  12. locked and limited conversation to collaborators on May 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions