Skip to content

ngOutletContext causes template to re-initialize on data changes #13407

Closed

Description

@parliament718

https://plnkr.co/edit/mUXkCli6CUEyNlbn2PZV?p=preview

I'm submitting a ... (check one with "x")

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Minimal reproduction of the problem with instructions

     <template #chartsManagerTemplate let-data="data">
         <charts-manager data="data"></charts-manager>
    </template>
    
     <template [ngOutletContext]="{ data: chartsData }"
            [ngTemplateOutlet]="chartsManagerTemplate">
     </template>

In the component:

     this.loadChartsData().subscribe(data => {

          //this causes the template to re-instantiate, I believe it should not.
          this.chartsData = data; 
     });

Current behavior

When data passed into [ngOutletContext] changes, the template and its nested components are re-instantiated.

Expected behavior

The expected behavior is for the template to not be re-instantiated, similar to if a template was not used. For example, this:

     <template [ngOutletContext]="{ data: chartsData }"
            [ngTemplateOutlet]="chartsManagerTemplate">
     </template>

should behave the same as:

<charts-manager data="chartsData"></charts-manager>

and NOT re-instantiate

What is the motivation / use case for changing the behavior?
Nested component should have the ability to control when they redraw, rather than it being forced simply by the use of . In my case, I would like to redraw charts with a transition.

Please tell us about your environment:

  • Angular version: 2.0.X
    2.0.0

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

  • Language: [all | TypeScript X.X | ES6/7 | ES5]

  • Node (for AoT issues): node --version =

Activity

  1. DzmitryShylovich commented on Dec 12, 2016

    @DzmitryShylovich
    Contributor

    Provide a small repro in plunkr

  2. parliament718 commented on Dec 12, 2016

    @parliament718
    Author
  3. changed the title [-]shades[/-] [+]ngOutletContext causes template to re-initialize on data changes[/+] on Dec 12, 2016
  4. DzmitryShylovich commented on Mar 3, 2017

    @DzmitryShylovich
    Contributor
  5. pkozlowski-opensource commented on Jul 19, 2017

    @pkozlowski-opensource
    Member

    The issue described here is a combination of 2 implementation decisions:

    • view engine / change detection engine will recreate objects literals used in expressions: https://plnkr.co/edit/vqBYylnvSkbJVgJW5LO5
    • ngTemplateOutlet will re-create templates as soon as a bound context changes:
      ngOnChanges(changes: SimpleChanges) {
      if (this._viewRef) {
      this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._viewRef));
      }
      if (this.ngTemplateOutlet) {
      this._viewRef = this._viewContainerRef.createEmbeddedView(
      this.ngTemplateOutlet, this.ngTemplateOutletContext);
      }
      }

    We could change implementation of the ngTemplateOutlet although it would be a bit tricky. before doing so I will dig into part of the view / CD engine that re-creates object literals.

  6. ghetolay commented on Jul 19, 2017

    @ghetolay
    Contributor

    I think the root problem for ngTemplateOutlet is ViewContainerRef.context to be readonly so we can't change a context but just create it once and then mutate it.
    When @DzmitryShylovich tried to fix that issue this was his main issue, if user provides a new context we can't just replace it but we would have to run a differ and mutate the actual context to shape it exactly like the new context being passed.
    I find it weird for Angular to enforce mutation of data here when it's more about immutable data everywhere else.

    So I think there should be a way to change the context (the reference), maybe through a function to ensure/prevent some behavior.

  7. added a commit that references this issue on Aug 7, 2017
    2871389
  8. added a commit that references this issue on Aug 7, 2017
    685cc26
  9. added a commit that references this issue on Aug 11, 2017
    b30fce5
  10. added 2 commits that reference this issue on Aug 26, 2017
    4c764aa
    5c93f5f
  11. angular-automatic-lock-bot commented on Sep 12, 2019

    @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 Sep 12, 2019
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

    area: commonIssues related to APIs in the @angular/common package

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions