How to re-render a component manually Angular 5

后端 未结 5 1301
耶瑟儿~
耶瑟儿~ 2020-12-31 01:38

Is there a way I can re render a component manually, say when a user clicks a button??

I\'ve seen similar posts but none of these worked for me for example here

相关标签:
5条回答
  • 2020-12-31 02:01

    If i understand you properly you are asking about ChangeDetectionStrategy Angular has two options

    enum ChangeDetectionStrategy {
      OnPush: 0
      Default: 1
    }
    

    If you use default it simply will "re-render" you view after each event such a click.

    If you are using OnPush, it will re-render if you use observable with | async or you can inject ChangeDetectorRef and "ask" to re-render

    constructor(private ref: ChangeDetectorRef) {
        setInterval(() => {
          this.numberOfTicks++;
          // the following is required, otherwise the view will not be updated
          this.ref.markForCheck();
        }, 1000);
      }
    

    But this is true if you are running inside of angular. Sometimes if you are listening to external services and you are running outside of NgZone you need to do ngZone.run

    this._ngZone.run(() => { console.log('Do change detection here'); });
    
    0 讨论(0)
  • 2020-12-31 02:04

    If you meant to manipulate the view (add, remove or reattach) then here is an example:

    import { Component, ViewContainerRef, AfterViewInit, ViewChild, ViewRef,TemplateRef} from '@angular/core';
    
    import { ChildComponent } from './child.component';
    
    @Component({
      selector: 'host-comp',
      template: `
        <h1>I am a host component</h1>
    
        <ng-container #vc><ng-container>
    
        <br>
    
        <button (click)="insertChildView()">Insert Child View</button>
        <button (click)="removeChildView()">Remove Child View</button>
        <button (click)="reloadChildView()">Reload Child View</button>
    
        <ng-template #tpl>
          <child-comp><child-comp>
        <ng-template>
    
      `
    })
    export class HostComponent implements AfterViewInit{
    
      @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
    
      @ViewChild('tpl', {read: TemplateRef}) tpl: TemplateRef<any>;
    
      childViewRef: ViewRef;
    
      constructor(){}
    
      ngAfterViewInit(){
        this.childViewRef = this.tpl.createEmbeddedView(null);
      }
    
      insertChildView(){
        this.vc.insert(this.childViewRef);
      }
    
      removeChildView(){
        this.vc.detach();
      }
    
      reloadChildView(){
        this.removeChildView();
        setTimeout(() =>{
          this.insertChildView();
        }, 3000);
      }
    }
    

    live example here

    0 讨论(0)
  • 2020-12-31 02:12

    You can use detectChanges() or markForCheck() to tell angular to re-render the component again.

    0 讨论(0)
  • 2020-12-31 02:13

    You could trick the router into rendering a fresh copy of current component by temporarily overriding route reuse strategy.. found in some other SO answer :)
    in ngOnInit:

    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
    
    0 讨论(0)
  • 2020-12-31 02:17

    I tried the answers in this thread but I had to do modifications to make it work. Let me share my working code.

    .html-----------------
    
    <button (click)="addChild()">ADD</button>
    <button (click)="removeChild()">REMOVE</button>
    
    <ng-container #vc></ng-container>
    <ng-template #tpl>
       <child-component id ="child-modal"></child-component>
    </ng-template>
    
    .ts---------------------
    import { Component, ViewChild, ViewContainerRef, TemplateRef, ViewRef } from '@angular/core';
    
    export class ParentComponent{
    
    @ViewChild('vc', { read: ViewContainerRef }) vc: ViewContainerRef;
    @ViewChild('tpl', { read: TemplateRef }) tpl: TemplateRef<any>;
    
    addChild(){
    let view = this.tpl.createEmbeddedView(null);
    this.vc.insert(view);
    }
    
    removeChild(){
     this.vc.clear();
    }
    

    This page was helpful. Make sure to add let view = this.tpl.createEmbeddedView(null); in addchild()

    0 讨论(0)
提交回复
热议问题