Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何以编程方式将ngBootstrap popover添加到元素?_Javascript_Angular_Fullcalendar_Ng Bootstrap_Fullcalendar 4 - Fatal编程技术网

Javascript 如何以编程方式将ngBootstrap popover添加到元素?

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

我目前正在使用angular v8应用程序中的日历

这是我使用的插件:

这是我在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>
(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>