Ngfor在mat-ltab标签中的使用

时间:2019-05-30 20:19:47

标签: angular

*ngFor(包含在角材料中)中使用mat-tab时遇到问题。我有一个按钮,单击该按钮可将代码复制为*ngFor。我的这段代码内的textArea有一个id = serReal{{j}},其中j是*ngFor的索引。我的参考无法正常工作。当我尝试在打字稿代码中获取元素时,它仅获取第一个(serReal0)。对于其他人,我会收到null。

我的HTML代码:

<!-- here I call it to duplicate -->
<button mat-icon-button (click)="addData()" type="button" id="add_icon"></button>

<!-- here it is my ngfor code which will duplicate -->
<mat-tab-group>
      <mat-tab *ngFor="let itemServ of itemsServ; let j = index;" [label] = label[j]>
            <div class="areaTexto">
                  <div class="mdc-text-field text-field mdc-text-field--fullwidth mdc-text-field--textarea">
                        <textarea class="campoTextoServReal" [id]="servReal{{j}}"></textarea>
                  </div>
            </div>
      </mat-tab>
</mat-tab-group>

<!-- here I call it to read the text areas by the id -->
<div class="divEncerraRel" id = apply>
      <button mat-raised-button (click) = 'setRelatorio()'>Encerrar Relatório</button>
</div>

我的TS代码:

itemsServ: number[] = [1];

addData() { 
  this.itemsServ.push(this.itemsServ.length + 1);
  this.label.push('Titulo');
}  

setRelatorio() {
  for (let i = 0; i < this.itemsServ.length; i++) {
     console.log((<HTMLInputElement>document.getElementById("servReal" + i)));
  } 
}

3 个答案:

答案 0 :(得分:0)

我认为您的问题的一部分是如何在HTML中设置ID。代替

<textarea class="campoTextoServReal" [id]="servReal{{j}}"></textarea>

尝试

<textarea class="campoTextoServReal" id="{{'servReal' + j }}"></textarea>

另外,当您期望<textarea id="servRealj">(其中j是期望的索引)时得到null的原因是因为它是一个选项卡组。当您在标签之间切换时,Angular将从DOM中删除mat-tab-body,因此,当您通过元素ID搜索它们时,它们不存在。之所以会看到这一点,是因为当您转到选项卡1或选项卡2时,只会看到servReal1和servReal2。

答案 1 :(得分:0)

通过将HtmlElements绑定到后端代码,您可以访问它们。 为此,准备了棱角分明的“ ViewChild属性装饰器”。

在您的HTML中,我添加了:

    <textarea #cmp class="campoTextoServReal" 
                       [id]="'servReal'+j"></textarea>

然后在BackEnd组件类中定义一个变量:

  @ViewChildren('cmp') components:QueryList<HTMLInputElement>;

并用于记录

 for (let i = 0; i < this.itemsServ.length; i++) {
    console.log(this.components._results[i].nativeElement.id);
     //console.log((<HTMLInputElement>document.getElementById("servReal" + i)));
  }

链接到stackbliz:https://stackblitz.com/edit/angular-material-example-lkbkm8?file=app/app.component.ts

答案 2 :(得分:0)

我看到的问题是:

  • 单独的状态跟踪数据this.label & this.itemsServ
  • 查询DOM以更新数据

在呈现它们之前,您应该真正从定义域或数据结构开始。

例如。

定义一个将保留您的数据结构的接口

export interface Item {
  id: number;
  label: string;
  data: string;
}`

然后定义一个要添加的函数:

addItem() { 
    const newIndex = this.items.length;
    const newItem = {
      id: newIndex,
      label: 'Titulo '+newIndex,
      data: 'data '+newIndex 
    } as Item

    this.items.push(newItem);
}

定义要更新的功能:

updateItem(id, data) {
    this.items.find((item) => item.id === id).data = data;
  }   

然后您就可以开始处理模板了

要添加,请点击按钮上方的addItem函数

(click)="addItem()"

要进行更新,请调用更新功能,根据您的情况,您可能希望在触发文本区域更改事件时更新数据

(change)="updateItem(item.id, data.value)"  

呈现所有标签

<mat-tab-group>
    <mat-tab *ngFor="let item of items; let j = index;" [label]="item.label">
        <div class="mdc-text-field text-field mdc-text-field--fullwidth mdc-text-field--textarea">
            <textarea class="campoTextoServReal" 
                #data 
                [id]="item.id" 
                (change)="updateItem(item.id, data.value)">
                {{item.data}}
            </textarea>
        </div>
    </mat-tab>
</mat-tab-group>

这样做可能会做更多的工作,但是它使您不必每次都要更新数据时都查询dom。

您可以找到完整的示例here