gpt4 book ai didi

javascript - 如何以编程方式将 ngBootstrap 弹出窗口添加到元素?

转载 作者:行者123 更新时间:2023-11-29 18:40:41 36 4
gpt4 key购买 nike

我目前正在我的 Angular v8 应用程序中处理日历。

这是我使用的插件:https://fullcalendar.io

这是我包含在我的 html 模板中的组件:

    <full-calendar
defaultView="dayGridMonth"
[editable]="true"
[eventLimit]="5"
[nowIndicator]="true"
[slotLabelFormat]="timeFormat"
[eventTimeFormat]="timeFormat"
[eventClassName]="'fc-event-brand'"
[minTime]="'08:00:00'"
[maxTime]="'24:00:00'"
[header]="{
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth, timeGridWeek, timeGridDay, listWeek'
}"
[plugins]="calendarPlugins"
[events]="calendarEvents"
(eventMouseEnter)="showPopover($event)"
(eventMouseLeave)="hidePopover($event)"
(eventRender)="renderTooltip($event)"></full-calendar>

但是如何向元素添加 ngBootstrap 弹出窗口或工具提示?

这是 renderTooltip():

renderTooltip(event) {
// bind ngBootstrap tooltip or popover to $event.el
}

最佳答案

我会创建一个简单的组件,它基本上只是一个弹出窗口包装器:

@Component({
template: `
<div class="fc-content" [ngbPopover]="template" container="body" triggers="manual">
<ng-content></ng-content>
</div>
`,
})
export class PopoverWrapperComponent {
template: TemplateRef<any>;

@ViewChild(NgbPopover, { static: true }) popover: NgbPopover;
}
  • template 属性将从我们的主要组件传递,因此我们可以创建我们想要的任何模板
  • 我们还拥有 NgbPopover 实例,因此我们可以稍后使用 popover.open(context)

还要确保您已将此组件添加到 NgModuleentryComponents 数组中:

@NgModule({
imports: [ BrowserModule, FullCalendarModule, NgbPopoverModule ],
declarations: [ AppComponent, PopoverWrapperComponent ],
entryComponents: [PopoverWrapperComponent],
\/
like this
bootstrap: [ AppComponent ]
})
export class AppModule { }

现在我们要将此组件动态渲染到 $event.el 元素中,并在 ng-content 中投影子节点。

import { Component, ComponentRef,
TemplateRef, ViewChild, ComponentFactoryResolver,
Injector, ApplicationRef } from '@angular/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';


@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
calendarPlugins = [dayGridPlugin];

calendarEvents = [
{ title: 'event 1', date: '2019-08-09', customProp1: 'customProp1', customProp2: 'customProp2' },
{ title: 'event 2', date: '2019-08-12', customProp1: 'customProp3', customProp2: 'customProp4' }
];

@ViewChild('popoverTmpl', { static: true }) popoverTmpl: TemplateRef<any>;

popoversMap = new Map<any, ComponentRef<PopoverWrapperComponent>>();

popoverFactory = this.resolver.resolveComponentFactory(PopoverWrapperComponent);

constructor(
private resolver: ComponentFactoryResolver,
private injector: Injector,
private appRef: ApplicationRef) {
}

renderTooltip(event) {
const projectableNodes = Array.from(event.el.childNodes)

const compRef = this.popoverFactory.create(this.injector, [projectableNodes], event.el);
compRef.instance.template = this.popoverTmpl;

this.appRef.attachView(compRef.hostView);
this.popoversMap.set(event.el, compRef);
}

destroyTooltip(event) {
const popover = this.popoversMap.get(event.el);
if (popover) {
this.appRef.detachView(popover.hostView);
popover.destroy();
this.popoversMap.delete(event.el);
}
}

showPopover(event) {
const popover = this.popoversMap.get(event.el);
if (popover) {
popover.instance.popover.open({ event: event.event });
}
}

hidePopover(event) {
const popover = this.popoversMap.get(event.el);
if (popover) {
popover.instance.popover.close();
}
}
}

这里的关键部分是我们如何渲染组件 dynamically with projectable nodes :

renderTooltip(event) {
const projectableNodes = Array.from(event.el.childNodes)

const compRef = this.popoverFactory.create(this.injector, [projectableNodes], event.el);
compRef.instance.template = this.popoverTmpl;

this.appRef.attachView(compRef.hostView)
this.popoversMap.set(event.el, compRef)
}

动态呈现的组件与 Angular 变化检测树无关,因此我们必须将其 View 添加到 ApplicationRef View 中,以便变化检测应该在那里工作。

确保您已在模板中订阅以下事件:

(eventRender)="renderTooltip($event)"
(eventDestroy)="destroyTooltip($event)"
(eventMouseEnter)="showPopover($event)"
(eventMouseLeave)="hidePopover($event)"

您还应该为弹出窗口定义模板,即:

<ng-template #popoverTmpl let-event="event">
<h6>{{ event.title }}</h6>
<div>
<p>{{ event.extendedProps.customProp1 }}</p>
<p>{{ event.extendedProps.customProp2 }}</p>
</div>
</ng-template>

Stackblitz Example

Stackblitz Example with @fullcalendar/angular/5.5.0

关于javascript - 如何以编程方式将 ngBootstrap 弹出窗口添加到元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57278854/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com