bootstrap5 无法将 undefined 或 null 转换为对象

bootstrap5 Cannot convert undefined or null to object

我正在尝试使用 angular 11 和 bootstrap 5 创建一个新的模态框,但出现了 belwo 错误

ERROR TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at Object.getDataAttributes (bootstrap.esm.js:875)
    at Modal._getConfig (bootstrap.esm.js:2821)
    at new Modal (bootstrap.esm.js:2681)
    at BaCarouselComponent.ngAfterViewInit (ba-carousel.component.ts:26)
    at callHook (core.js:2573)
    at callHooks (core.js:2542)
    at executeInitAndCheckHooks (core.js:2493)
    at refreshView (core.js:9537)
    at refreshComponent (core.js:10637)

组件代码:

import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {Modal} from 'bootstrap';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, AfterViewInit {

  modalDirect: Modal | undefined;
  @ViewChild('demoModal') demoModal: ElementRef<HTMLElement> | any;
  constructor() { }

  ngOnInit(): void {
    // this.modalDirect = new Modal(this.demoModal, {});
  }

  ngAfterViewInit(): void {
    this.modalDirect = new Modal(this.demoModal, {});
    console.log('ngAfterViewInit: %o', this.demoModal);
  }

  open(element: Element): void {
    this.modalDirect = new Modal(element, {});
    // this.modalDirect.Modal.open(element);
    // this.modal.show();
  }

}

Html模板代码:


<div
  #demoModal class="modal fade"
  data-bs-backdrop="static"
  data-bs-keyboard="false"
  tabindex="-1"
  aria-labelledby="staticBackdropLabel"
  aria-hidden="true">

  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="staticBackdropLabel">Modal title</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>

      <div class="modal-body">
        ...
      </div>

      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Understood</button>
      </div>

    </div>

  </div>

</div>

您应该将 nativeElement 传递给 Modal

this.modalDirect = new Modal(this.demoModal.nativeElement, {});

stackblitz link

演示使用 nativeElement StackBlitz Demo Link

当您使用 @ViewChild() 访问 dom 元素时,其 angular 从 DOM 获取 ElementRef 的方式,并且 Angular ElementRef 是一个包装视图内的本机元素。所以简单地访问真实的 DOM 我们需要 nativeElement 而这个实例 returns 我们当前真实的 DOM 对象。这就是为什么我们在使用@ViewChild() 访问真正的 DOM.

时需要 nativeElement
ngAfterViewInit(): void {
   this.modalDirect = new Modal(this.demoModal.nativeElement, {});
}

现在,第二种情况是,您不需要使用@ViewChild(),只需将模板引用变量传递给 .open() 方法,并创建新的 Modal() 实例来自 open() 方法。在这种情况下,您直接将真实的 DOM 传递给 open() 方法,这就是为什么您不需要 nativeElement.

open(element: any): void {
  this.modalDirect = new Modal(element, {});
  this.modalDirect.show();
} 

并像这样从模板调用这个打开方法..

<div #demoModal class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"

aria-labelledby="staticBackdropLabel" aria-hidden="true"> --------------

 <button class="btn btn-secondary" (click)="open(demoModal)">open</button>

在上面,demoModal是div标签的模板引用变量,我们将这个元素引用直接传递给open方法,所以这里不需要使用nativeElement。

没有 nativeElement 的演示 Stackblitz Link