Javascript 如何以编程方式将ngBootstrap popover添加到元素?
我目前正在使用angular v8应用程序中的日历 这是我使用的插件: 这是我在html模板中包含的组件:Javascript 如何以编程方式将ngBootstrap popover添加到元素?,javascript,angular,fullcalendar,ng-bootstrap,fullcalendar-4,Javascript,Angular,Fullcalendar,Ng Bootstrap,Fullcalendar 4,我目前正在使用angular v8应用程序中的日历 这是我使用的插件: 这是我在html模板中包含的组件: <full-calendar defaultView="dayGridMonth" [editable]="true" [eventLimit]="5" [nowIndicator]="true" [slotLabel
<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>
(eventRender)="renderTooltip($event)"
(eventDestroy)="destroyTooltip($event)"
(eventMouseEnter)="showPopover($event)"
(eventMouseLeave)="hidePopover($event)"
我将创建一个简单的组件,它基本上只是一个popover包装器:
@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;
}
现在,我们将动态地将该组件呈现到$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();
}
}
}
动态渲染组件与角度变化检测树没有关系,因此我们必须将其视图添加到ApplicationRef
视图中,以便变化检测可以在那里工作
确保您已在模板中订阅了以下活动:
<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>
(eventRender)="renderTooltip($event)"
(eventDestroy)="destroyTooltip($event)"
(eventMouseEnter)="showPopover($event)"
(eventMouseLeave)="hidePopover($event)"
您还应该为popover定义模板,即:
<ng-template #popoverTmpl let-event="event">
<h6>{{ event.title }}</h6>
<div>
<p>{{ event.extendedProps.customProp1 }}</p>
<p>{{ event.extendedProps.customProp2 }}</p>
</div>
</ng-template>
{{event.title}}
{{event.extendedProps.customProp1}
{{event.extendedProps.customProp2}
您可以在此处看到演示:在页面源代码中搜索“工具提示”,您将看到实现。@yurzui,clap,clap,clap好的,此解决方案存在问题-如果您使用interactionPlugin,它会破坏大小调整功能,可以通过从
popopoverappercomponent
中删除fc content
类来修复。它添加了两个嵌套的fc content
div,而不是一个。否则它工作得很好,谢谢!伟大的解决方案,竖起大拇指!冲突的“fc事件”类问题可以通过使用popover属性PopoOverClass提供您自己的css类来解决。因此,在PopOverrapPerComponent模板中,可以如下所示:StackBlitz示例似乎是broken@DanielFlippance不,你没有看到任何东西,因为它用的是旧的日期。我更新它以使用当前日期
<ng-template #popoverTmpl let-event="event">
<h6>{{ event.title }}</h6>
<div>
<p>{{ event.extendedProps.customProp1 }}</p>
<p>{{ event.extendedProps.customProp2 }}</p>
</div>
</ng-template>