Home » Javascript » javascript – Angular 2+ Access/Change Variable from Lazy-Loaded component

javascript – Angular 2+ Access/Change Variable from Lazy-Loaded component

Posted by: admin February 26, 2020 Leave a comment

Questions:

I want after lazy-load will be use NewDataSet

I’ve tried add @Input() DataList or private DataList, but not working.

app.component.html:

<ul>
<li *ngFor="let Data of DataList">{{Data.Name}}></li>
</ul>

<button (click)='getLazy()'>Lazy Load New DataSet</button>

app.component.ts:

import OldDataSet from '../assets/OldDataSet.json';

...

export class AppComponent {

DataList:Array<Object> = OldDataSet;

  constructor(
    private viewContainerRef: ViewContainerRef,
    private cfr: ComponentFactoryResolver
  ) {}

  async getLazy() {
    this.viewContainerRef.clear();
    const { Lazy1Component } = await import('./lazy1.component');

    this.viewContainerRef.createComponent(
      this.cfr.resolveComponentFactory(Lazy1Component)
    );
  }
}

lazy1.component.ts:

import NewDataSet from '../assets/NewDataSet.json';

...

export class Lazy1Component implements OnInit {

  ngOnInit(): void {
    this.DataList = NewDataSet
  }
}
How to&Answers:

https://stackblitz.com/edit/angular-dynamic-component-problem

please take a look a live version.
I hope this solution meet your needs.

app.component.ts

import {
  Component,
  ViewChild,
  ComponentFactoryResolver,
  ViewContainerRef,
  Type
} from "@angular/core";
import { PlaceholderDirective } from "./placeholder.directive";

import { DatasetAComponent } from "./dataset-a.component";
import { DatasetBComponent } from "./dataset-b.component";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html"
})
export class AppComponent {
  hostViewContainerRef: ViewContainerRef;

  @ViewChild(PlaceholderDirective, { static: false })
  datasetHost: PlaceholderDirective;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {}

  onLoadA() {
    this.loadNewDataset(DatasetAComponent, "dataset A loaded.");
  }

  onLoadB() {
    this.loadNewDataset(DatasetBComponent, "dataset B loaded.");
  }

  onClear() {
    this.hostViewContainerRef.clear();
  }

  loadNewDataset(
    datasetComponent: Type<DatasetAComponent> | Type<DatasetBComponent>,
    message: string
  ) {
    const datasetCmpFactory = this.componentFactoryResolver.resolveComponentFactory(
      datasetComponent
    );

    this.hostViewContainerRef = this.datasetHost.viewContainerRef;

    this.hostViewContainerRef.clear();

    const componentRef = this.hostViewContainerRef.createComponent(
      datasetCmpFactory
    );
    componentRef.instance.message = message;
  }
}

dataset-a.component.ts

import { Component, Input } from "@angular/core";
import colors from "./data/a.json";

@Component({
  templateUrl: "./dataset-a.component.html"
})
export class DatasetAComponent {
  @Input() message: string;
  dataset = colors;
}

app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";

import { AppComponent } from "./app.component";
import { PlaceholderDirective } from "./placeholder.directive";

import { DatasetAComponent } from "./dataset-a.component";
import { DatasetBComponent } from "./dataset-b.component";

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [
    AppComponent,
    PlaceholderDirective,
    DatasetAComponent,
    DatasetBComponent
  ],
  bootstrap: [AppComponent],
  entryComponents: [DatasetAComponent, DatasetBComponent]
})
export class AppModule {}

app.component.html

<h1>using view container ref</h1>
<button (click)="onLoadA()">Dataset A</button> | 
<button (click)="onLoadB()">Dataset B</button> |
<button (click)="onClear()">Clear View</button>
<br />
<ng-template appPlaceholder></ng-template>