如何选择*ngIf渲染的动态元素

Joe*_*Joe 6 javascript angular

正如下面提供的代码.我试图选择由ngIf生成的动态元素但是失败了.

我总共用了两种方法.

  1. ElementRef和querySelector

组件模板:

    `<div class="test" *ngIf="expr">
      <a id="button">Value 1</a>
    </div>
    <div class="test" *ngIf="!expr">
      <a id="button">Value 2</a>
    </div>`
Run Code Online (Sandbox Code Playgroud)

组件类:

    expr: boolean;

    constructor(
      private elementRef: ElementRef,
    ) {
    }

    ngOnInit(): void{
    //Call Ajax and set the value of this.expr based on the callback;
    //if expr == true, then show text Value 1; 
    //if expr == false, then show text Value 2;
    }
    ngAfterViewInit(): void{
      console.log(this.elementRef.nativeElement.querySelector('#button'));
    }
Run Code Online (Sandbox Code Playgroud)

输出结果是null.

  1. @ViewChild

组件模板:

    `<div class="test" *ngIf="expr">
      <a #button>Value 1</a>
    </div>
    <div class="test" *ngIf="!expr">
      <a #button>Value 2</a>
    </div>`
Run Code Online (Sandbox Code Playgroud)

组件类:

    @ViewChild('button') button: elementRef;

    expr: boolean;

    ngOnInit(): void{
    //Call Ajax and set the value of this.expr based on the callback;
    //if expr == true, then show text Value 1; 
    //if expr == false, then show text Value 2;
    }

    ngAfterViewInit(): void{
      console.log(this.button);
    }
Run Code Online (Sandbox Code Playgroud)

输出结果是undefined;

有没有办法获得*ngIf生成的动态dom?


最后,问题已经通过@ViewChildren解决了.

要记录更新的结果,必须使用单独的功能.

例如:

错误的代码:

    @ViewChildren('button') buttons: ElementRef;

    function(): void{
      this.expr = true; // Change expression then the DOM will be changed;
      console.log(this.buttons.toArray()); // This is wrong because you will still get the old result;
    }
Run Code Online (Sandbox Code Playgroud)

正确的代码:

    @ViewChildren('button') buttons: ElementRef;

    function(): void{
      this.expr = true; // Change expression then the DOM will be changed;
    }
    ngAfterViewInit(): void{
      this.buttons.changes.subscribe( e => console.log(this.buttons.toArray()) ); // This is right and you will get the latest result;
    }
Run Code Online (Sandbox Code Playgroud)

Gün*_*uer 5

*ngIf="expr"表达式为假时,您无法获取该元素,因为该元素不存在。

该值尚未在 中设置ngOnInit(),仅在ngAfterViewInit()调用时设置。

Plunker 示例

@Component({
  selector: 'my-app',
  template: `
    <div class="test" *ngIf="prop">
      <a #button id="button1">button1</a>
    </div>
    <div class="test" *ngIf="!boolean">
      <a id="button2">button2</a>
    </div>`
 ,
})
export class App {
  @ViewChild('button') button: ElementRef;

  prop:boolean = true;

  ngAfterViewInit() {
    console.log(this.button);
  }
}
Run Code Online (Sandbox Code Playgroud)

Plunker 示例 ViewChildren

@Component({
  selector: 'my-app',
  template: `
    <button (click)="prop = !prop">toggle</button>
    <div class="test" *ngIf="prop">
      <a #button id="button1">button1</a>
    </div>
    <div class="test" *ngIf="!boolean">
      <a #button id="button2">button2</a>
    </div>`
 ,
})
export class App {
  @ViewChildren('button') button: QueryList<ElementRef>;

  prop:boolean = true;

  ngAfterViewInit() {
    console.log(this.button.toArray());
    this.button.changes.subscribe(val => {
      console.log(this.button.toArray());
    });

  }
}
Run Code Online (Sandbox Code Playgroud)


Cas*_*ath 5

不完全是最好的,但我使用 [ngClass] 而不是 *ngIf 处理类似的情况。只需创建一个带有“display: none”的类并在需要时隐藏元素即可。使用@ViewChild选择的元素可以毫无问题地访问。现在,您可以在寻找更好或更优雅的解决方案时使用这个小“技巧”​​。前任。

.hide-element{
    display: none;
}

<div class="test" [ngClass]="expr === 'yourTest' ? 'hide-element' : null">
  <a #b id="button1" (click)="onButton1(b)">button1</a>
</div>
Run Code Online (Sandbox Code Playgroud)

如果您正在处理一些异步返回,您可以使用异步管道

<div class="test" [ngClass]="(expr | async) === 'yourTest' ? 'hide-element' : null">
      <a #b id="button1" (click)="onButton1(b)">button1</a>
</div>
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。