dynamically insert mat-checkbox

家住魔仙堡 提交于 2020-03-04 11:29:15

问题


I want to dynamically insert a <mat-checkbox> element into a component. and I inserted two <mat-checkbox> elements. one inserted statically (i.e into the template file directly).

and the other one inserted dynamically, and contains a <mat-checkbox> and another normal checkbox <input type="checkbox" />

the first one (the statically inserted one) rendered without any problem.

also the normal input inserted dynamically without any problem.

but the <mat-checkbox> that dynamically inserted didn't render as expected.

component.html:

<mat-checkbox> checkbox (static) </mat-checkbox>

<div [innerHTML] = "test2">

component.ts:

 this.test= ` 
     <mat-checkbox>mat-checkbox</mat-checkbox><br />
     <input type="checkbox" /> normal checkbox   
  `

  this.test2 = this.sanitizer.bypassSecurityTrustHtml(this.test);

I created a Reproduction on stackblitz:

https://stackblitz.com/edit/angular-hsjevo

also I need to create checkboxes from categories, and append some extra spaces before each sub-category

i.e:

  • category
    • sub category
      • sub of sub category
  • category2

each category or sub-category is <mat-checkbox value="$id"> $title


回答1:


innerHTML property of div tag can only parse and render regular HTML elements like input, etc. To dynamically create Angular components like mat-checkbox, you need to inform Angular about those components. Let's see how this can be done below:

We need a placeholder in the AppComponent template where we can add the mat-checkbox component dynamically. We can use <ng-template> tag as a placeholder in this case.

app.component.html

<mat-checkbox>mat-checkbox (static)</mat-checkbox> <hr />


dynamic angular component:<br/>
<ng-template #placeholder></ng-template>

In AppComponent typescript file, we need to refer this placeholder and append the mat-checkbox component. Find the inline comments for explanation.

app.component.ts

import {
  Component,
  ComponentFactoryResolver,
  OnInit,
  Renderer2,
  ViewChild,
  ViewContainerRef
} from '@angular/core';
import {MatCheckbox} from '@angular/material';

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  // Get reference to the ng-template placeholder tag
  @ViewChild('placeholder', {read: ViewContainerRef, static: true}) placeholder: ViewContainerRef;

  constructor(
    private resolver: ComponentFactoryResolver,
    private renderer: Renderer2) {}

  ngOnInit() {
    this.createComponent();
  }

  createComponent() {
    // creating the mat-checkbox tag body content
    let content = this.renderer.createText(' mat-checkbox (dynamic)');
    // clear any previously appended element or component
    this.placeholder.clear();
    // resolve the MatCheckbox component and get the factory class to create the component dynamically
    let factory = this.resolver.resolveComponentFactory(MatCheckbox);
    // create the component and append to the placeholder in the template
    let ref = this.placeholder.createComponent(factory);
    // set the mat-checkbox body content
    (ref.location.nativeElement as HTMLElement).appendChild(content);
  }
}

In order for the above code to work, we need to inform Angular that we would be expecting to resolve the MatCheckbox component at runtime. Make the following changes in app.module.ts.

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { MatCheckboxModule, MatCheckbox } from '@angular/material';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';


@NgModule({
  imports:      [ BrowserModule, FormsModule, MatCheckboxModule ],
  declarations: [ AppComponent, HelloComponent ],
  // Inform Angular about those components which will be created dynamically by including them in entryComponents field
  entryComponents: [ MatCheckbox ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Now you should be able to see the mat-checkbox created dynamically at runtime. View the complete example here (https://stackblitz.com/edit/angular-e7vhue)

For more information, refer this article.

Hope this helped your query.



来源:https://stackoverflow.com/questions/60264854/dynamically-insert-mat-checkbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!