3

我想使用同名的模板引用变量在@ViewChildren.

元数据属性

selector - 用于查询的指令类型或名称。
read - 从查询的元素中读取不同的标记。

但是,我得到了一个模板解析错误

Reference "#abc" is defined several times

样本:

import {AfterViewInit, Component, Directive, Input, QueryList, ViewChildren, ElementRef} from '@angular/core';

@Directive({selector: 'pane'})
export class Pane {
  @Input() id: string;
}

@Directive({selector: 'pane1'})
export class Pane1 {
  @Input() id: string;
}

@Component({
  selector: 'app-root',
  template: `
    <span #abc id="1"></span>
    <pane1 #abc id="2"></pane1>
    <pane #abc id="3" *ngIf="shouldShow"></pane>
    <button (click)="show()">Show 3</button>
    <button (click)="hide()">Hide 3</button>

    <div>panes: {{serializedPanes}}</div> 
  `,
})
export class ViewChildrenComp implements AfterViewInit {
  @ViewChildren('abc') panes: QueryList<ElementRef>;
  serializedPanes: string = '';

  shouldShow = false;

  show() { this.shouldShow = true; }
  hide() { this.shouldShow = false; }

  ngAfterViewInit() {
    this.calculateSerializedPanes();
    this.panes.changes.subscribe(
      (r) => {
      this.calculateSerializedPanes(); 
    });
  }

  calculateSerializedPanes() {
    setTimeout(
      () => {
        this.serializedPanes = this.panes.map(p => p.nativeElement.id).join(', '); 
      }, 0);
  }
}

问题:
1. 是否可以在模板中定义同名的模板引用变量?
2. 如何使用同一个选择器查询多个元素,而不是单独定义名称?

4

1 回答 1

4

您不能在一个模板中定义同名的模板引用变量。

您只能在不同的模板中定义它,包括EmbeddedViewTemplate,即

<div #abc>
  <ng-template #abc>
    <ng-template>
      <div #abc></div>
    </ng-template>
  </ng-template>
</div>

应该管用

或者

<div #abc>
  <ng-template #abc>
    <div #abc></div>
  </ng-template>
  <ng-template #abc>
    <div #abc></div>
  </ng-template>
</div>

也应该工作

如何使用相同的选择器查询多个元素,而不是单独定义名称?

您可以定义指令,如

@Directive({selector: '[id]'}) 
export class Abc {
  constructor(public elRef: ElementRef) {}
}

选择器可以[abc]然后你需要abc为所有元素添加属性

<span abc id="1"></span>
<pane1 abc id="2"></pane1>
<pane abc id="3" *ngIf="shouldShow"></pane>

但既然你已经定义了id我用它作为选择器

之后,您可以使用Abc上述指令作为选择器@ViewChildren

@ViewChildren(Abc) panes: QueryList<ElementRef>;

this.serializedPanes = this.panes.map(p => p.elRef.nativeElement.id).join(', '); 

Plunker 示例

但是有一些技巧可以帮助我们多次拥有一个变量。 只需将您的元素包装到另一个元素中,

 <div>
   <span #abc id="1"></span>
   <pane1 #abc id="2"></pane1>
   <pane #abc id="3" *ngIf="shouldShow"></pane>
 </div>

或者

<ng-container>
  <span #abc id="1"></span>
  <pane1 #abc id="2"></pane1>
  <pane #abc id="3" *ngIf="shouldShow"></pane>
</ng-container>

Plunker 示例

于 2017-07-12T04:33:40.650 回答