【问题标题】:How to programmatically open ngbootstrap popover for a d3 element?如何以编程方式为 d3 元素打开 ngbootstrap 弹出框?
【发布时间】:2018-02-21 20:24:24
【问题描述】:

我想为 D3 元素打开一个弹出框。

基本上这意味着我的 component.html 文件几乎是空的,只包含弹出框模板:

<ng-template #popContent let-greeting="greeting">{{greeting}}, <b>{{name}}</b>!</ng-template>

我不能正常使用

[ngbPopover]="popContent" popoverTitle="Greeting" #p="ngbPopover" triggers="manual"

属性,因为目标 D3 元素还不存在

我需要的是能够以某种方式调用弹出框的 open 函数,传递弹出框的内容和位置。 在我的组件中是这样的:

public showPopover(node, text){ // node is the DOM element for which to show popover
 ... what should go here? ...
}

【问题讨论】:

  • documentation 有一个手动触发弹出框的示例(滚动到上下文和手动触发)。
  • @Mark 但它没有说明如何将其附加到任意 dom 元素。

标签: javascript twitter-bootstrap angular d3.js ng-bootstrap


【解决方案1】:

看起来 API 没有提供在 dynamic elements 上创建弹出框的方法(请参阅容器)。由于 Angular 希望您避免直接访问 DOM,因此您必须通过模板创建弹出窗口。所以,我会在“空白”元素上创建它,然后将它移动到您的动态元素中。也就是说,一旦你移动它,你就必须手动触发它,因为 events 都将在“空白”元素上。像这样的:

模板

<!-- empty span to create the popover on -->
<!-- note the "manual" trigger -->
<span ngbPopover="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." popoverTitle="Popover on top"
        #popover="ngbPopover" triggers="manual">
</span>

<div #base></div> <!-- where my dynamic element will go -->

控制器

import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
import {Component, ViewChild, ngAfterViewInit, ElementRef, Renderer2} from '@angular/core';

@Component({
  selector: 'ngbd-popover-tplwithcontext',
  templateUrl: 'src/popover-tplwithcontext.html'
})

export class NgbdPopoverTplwithcontext implements ngAfterViewInit {

  @ViewChild('popover') public popover: NgbPopover;
  @ViewChild('base') el:ElementRef;

  ngAfterViewInit(){

    // create dynamic element
    let s = d3.select(this.el.nativeElement)
      .append('button')
      .html('Dynamically Added!')
      // manual open
      .on('click', () => { this.openPop(); })

    // assign popover our new element
    this.popover._elementRef = new ElementRef(s.node());
  }

  // handle the opening/closing
  public openPop(): void {
    console.log(this)
    this.popover.isOpen() ? this.popover.close() : this.popover.open();
  }
}

这是running example

【讨论】:

  • 替代方案是在您的组件中创建 NgbPopover 的实例。它有一长串依赖项,您必须将它们注入到您的组件中,唯一的原因是传递给 NgbPopover。在我看来,这个 hack 是一个更易于维护的解决方案!
  • 在 ngbootstrap 版本 9.0.2 中,它说 [Property '_elementRef' 是私有的,只能在类 'NgbPopover' 中访问"]
【解决方案2】:

您好,谢谢,但我必须在定义文件 popover.d.ts 中添加一个您需要将属性“.elementRef”更改为 public 的东西

export declare class NgbPopover implements OnInit, OnDestroy, OnChanges {
public _elementRef;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多