首页 > 解决方案 > Bootstrap popover 在 *ngIf 内以角度失败

问题描述

我正在尝试在容器内显示弹出框,但它不起作用,

如果我删除 *ngIf 它可以工作

如果 *ngIf 不渲染,在哪里

<div class="container" *ngIf="data" >
  <button 
    class="popover" 
    data-trigger="hover" 
    data-toggle="tooltip" 
    data-content="hello" 
    data-container="body">
  <mat-icon>
   info
  </mat-icon>
 </button>
</div>

//ts文件

export class SomeComponent implements OnInit {
//... variables 
//... constructor

  ngOnInit() {
      $('.popover').popover({
        boundary: 'viewport',
        placement: 'top',
        container:'body',
        sanitize: true,
        appendToBody: true
      })

  }
}```

标签: javascripthtmlangulartwitter-bootstrapangular-material

解决方案


这不起作用,因为当 ngOnInit() 被 Angular 调用时,div.container 不是由 Angular 渲染的。相反,您可以使用 AfterViewInit Lifecycle 挂钩,如下所示。

注意带有ngIf的段落不能在ngOnInit中加载,但可以在ngAfterViewInit中加载。

Stackblitz 代码:https ://stackblitz.com/edit/angular-ngif-lifecycle-hook

组件.html

<p id="p1">
  Without ngIf
</p>

<p id="p2" *ngIf="data">
  With ngIf
</p>

组件.ts

import { Component, VERSION, OnInit, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
 styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit, AfterViewInit{
    data = {random: 'text'};

    ngOnInit() {
        const withoutNgIf = document.getElementById('p1');
        const withNgIf = document.getElementById('p2');

        console.log('OnInit without ngIf: ', withoutNgIf);
        # Output: HTMLParagraphElement
        console.log('OnInit with ngIf: ', withNgIf);
        # Output: null
    }

    ngAfterViewInit() {
        const withNgIf = document.getElementById('p2');  
        console.log('AfterViewInit with ngIf: ', withNgIf);
        # Output: HTMLParagraphElement
    }
}

我希望这可以帮助您理解问题。

提示:如果您使用 angular,我建议使用 ViewChild 装饰器来访问 DOM 而不是 jquery。(例如:https ://dev.to/danielpdev/how-to-use-viewchild-decorator-in-angular-9-i0 )


推荐阅读