Smokey Dawson
Smokey Dawson

Reputation: 9230

How to re-render a component manually Angular 5

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

For example,

renderComponent() {
   // force component re-render
}

Upvotes: 33

Views: 117116

Answers (9)

rob9099
rob9099

Reputation: 69

Maybe use window.location.reload()

Upvotes: -1

Nicolas Gehlert
Nicolas Gehlert

Reputation: 3253

You can use this Angular library ngx-rerender https://www.npmjs.com/package/ngx-rerender

<stuff-to-rerender *mcRerender="trigger">Some Content</stuff-to-rerender>
class MyComponent {
  public trigger: number = 0;

  public rerender(): void {
    this.trigger++;
  }
}

Whenever you call the rerender function your component is being completely rerendered

Upvotes: 1

Toshiaki Aizawa
Toshiaki Aizawa

Reputation: 141

HTML

<app-component1 *ngIf="FLAG"></app-component1>

TS

  constructor(private changeDetectorRef: ChangeDetectorRef) {
      this.FLAG = true
  }

  renderComponent() {
      this.FLAG = false;
      this.changeDetectorRef.detectChanges();
      this.FLAG = true;
  }

Upvotes: 9

Anh Nguyen
Anh Nguyen

Reputation: 1234

I have created a Directive for this re-rendering purpose

/**
 * Example:
 *
 * <ng-container *rerender='changingInput'>
 *    this content will be re-rendered everytime `changingInput` changes
 * </ng-container>
 */

import { Directive,
         Input,
         TemplateRef,
         ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[rerender]'
})
export class RerenderDirective {
  constructor(
    private templateRef:    TemplateRef<any>,
    private viewContainer:  ViewContainerRef
  ) {}

  // if detects changes of the input `val`, clear and rerender the view
  @Input() set rerender(val) {
    this.viewContainer.clear();
    this.viewContainer.createEmbeddedView(this.templateRef);
  }
}

Check out my Gist for the latest update.

Upvotes: 9

Rincy Philip
Rincy Philip

Reputation: 47

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()

Upvotes: 1

Eugen  Bogdanovich
Eugen Bogdanovich

Reputation: 211

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;

Upvotes: 3

Sagar Kharche
Sagar Kharche

Reputation: 2681

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

Upvotes: 9

sugarme
sugarme

Reputation: 761

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

Upvotes: 23

Vova Bilyachat
Vova Bilyachat

Reputation: 19484

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'); });

Upvotes: 12

Related Questions