【问题标题】:dynamically insert mat-checkbox动态插入 mat-checkbox
【发布时间】:2020-06-01 12:39:23
【问题描述】:

我想将<mat-checkbox> 元素动态插入到组件中。 我插入了两个<mat-checkbox> 元素。一个静态插入(即直接插入模板文件)。

另一个是动态插入的,包含一个<mat-checkbox>和另一个普通复选框<input type="checkbox" />

第一个(静态插入的)渲染没有任何问题。

正常的输入也是动态插入的,没有任何问题。

但动态插入的<mat-checkbox> 未按预期呈现。

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

我在 stackblitz 上创建了一个 Reproduction:

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

我还需要从类别中创建复选框,并在每个子类别之前附加一些额外的空格

即:

  • 类别
    • 子类
      • 子类的子类
  • 类别2

每个类别或子类别是&lt;mat-checkbox value="$id"&gt; $title

【问题讨论】:

  • 这不是您应该使用 Angular 在您的组件上显示动态内容的方式。例如,使用*ngIf / *ngFor 来决定是否应该根据组件属性呈现某些内容。
  • 请看一下,这解决了我的问题参考:stackoverflow.com/questions/47384092/…
  • 我不想有条件地加载组件。我想动态添加一些 html 输入到现有组件@ThomasSchneiter

标签: angular angular-material material-design


【解决方案1】:

div 标签的innerHTML 属性只能解析和渲染常规的HTML 元素,如输入等。要动态创建像mat-checkbox 这样的Angular 组件,您需要通知Angular 这些组件。让我们看看如何在下面做到这一点:

我们需要在 AppComponent 模板中有一个占位符,我们可以在其中动态添加 mat-checkbox 组件。在这种情况下,我们可以使用&lt;ng-template&gt; 标签作为占位符。

app.component.html

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


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

在 AppComponent typescript 文件中,我们需要引用这个占位符并附加 mat-checkbox 组件。查找内联 cmets 进行说明。

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

为了使上述代码能够正常工作,我们需要通知 Angular 我们希望在运行时解析 MatCheckbox 组件。在 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 { }

现在您应该能够看到在运行时动态创建的 mat-checkbox。 在此处查看完整示例 (https://stackblitz.com/edit/angular-e7vhue)

有关详细信息,请参阅此article

希望这对您的查询有所帮助。

【讨论】:

  • 好的,我想获取一个将转换为 的输入数组,每个条目都包含 {title, id}。确实我想形成复选框以在每个子类别之前附加一些额外的空格,所以我想将输入作为字符串获取
  • @Sheldeeb 有趣。您可以使用 ViewContainerRef 引用的 createComponent 方法开始将多个 mat-checkbox 组件附加到 ng-template 占位符。我已经为这个用例更新了 stackblitz 中的应用程序。
  • 我刚刚给你投票 +1 并接受了你的回答@sharavan
  • 如何为动态加载的组件添加额外的指令例如:&lt;mat checkbox [myDirective]="something"&gt;..&lt;/mat-checkbox&gt;
  • @Sheldeeb 据我所知,没有办法以编程方式添加/删除指令。相反,您可以创建一个包装器组件(例如,)并通过包装器组件输入控制指令值。看看解决方案here 也是如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 2020-03-16
  • 1970-01-01
相关资源
最近更新 更多