You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何程序化关闭Syncfusion日程组件的Quick Info模板?

在React中关闭Syncfusion日历Quick Info模板的解决方法

问题描述

我用Syncfusion开发日历视图的弹出式Quick Info模板,参考过相关论坛方案但不兼容React。已实现自定义头部和内容模板,但头部的关闭按钮点击后毫无反应,求React环境下通过代码关闭该Quick Info模板的可行方案。

现有代码如下:

const handleCloseQuickInfoTemplate = e => {
  this.CloseQuickInfoPopup(); // 尝试通过此方法关闭弹窗,但无效
};

const headerTemplate = props => {
  console.log('headerTemplate', props);
  return (
    <div class="e-popup-header">
      <div class="e-header-icon-wrapper">
        <button
          class="e-edit e-control e-btn e-lib e-flat e-round e-small e-icon-btn"
          title="Edit"
        >
          <span class="e-btn-icon e-icons e-edit-icon"></span>
        </button>
        <button
          class="e-delete e-control e-btn e-lib e-flat e-round e-small e-icon-btn"
          title="Delete"
          onClick={() => setOpenDeletePopup(true)}
        >
          <span class="e-btn-icon e-icons e-delete-icon"></span>
        </button>
        <button
          class="e-close e-control e-btn e-lib e-flat e-round e-small e-icon-btn"
          title="Close"
          onClick={handleCloseQuickInfoTemplate}
        >
          <span class="e-btn-icon e-icons e-close-icon"></span>
        </button>
      </div>
      <div class="e-subject-wrap">
        <div class="e-subject e-text-ellipsis" title={props.Subject}>
          {props.Subject}
        </div>
      </div>
    </div>
  );
};

const contentTemplate = props => {
  let startDateConvert = moment(props.StartTime.toString()).format(
    'MMMM DD, YYYY'
  );
  let startTimeConvert = moment(props.StartTime.toString()).format('h:mm A');
  let endTimeConvert = moment(props.EndTime.toString()).format('h:mm A');

  return (
    <div className="template-wrap">
      <div class="e-date-time">
        <div class="e-date-time-icon e-icons"></div>
        <div class="e-date-time-wrapper e-text-ellipsis">
          <div class="e-date-time-details e-text-ellipsis">
            {startDateConvert} ({startTimeConvert}&nbsp;-&nbsp;
            {endTimeConvert})
          </div>
        </div>
      </div>
      <div class="e-location">
        <div class="e-location-icon e-icons"></div>
        <div class="e-location-details e-text-ellipsis">{props.Location}</div>
      </div>
      <div class="e-resource">
        <div class="e-resource-icon e-icons"></div>
        <div class="e-resource-details e-text-ellipsis">
          {props.DoctorList}
        </div>
      </div>
      <div class="e-location">
        <div class="e-description-icon e-icons"></div>
        <div class="e-location-details e-text-ellipsis">{props.Type}</div>
      </div>
      <div class="e-location">
        <div class="flaticon-file-1 icon-md"></div>
        <div
          class="e-location-details e-text-ellipsis"
          style={{ paddingLeft: '4%' }}
        >
          {props.Status}
        </div>
      </div>
    </div>
  );
};

<ScheduleComponent
  cssClass="virtual-scrolling schedule-header-bar"
  width="100%"
  height="100%"
  resizeStop={rescheduleDrag.bind()}
  dragStop={rescheduleDrag.bind()}
  locale={checkLocal()}
  currentView={schedularView}
  eventSettings={{
    dataSource: list.concat(organizerList),
    eventTemplate: eventTemplate.bind(),
  }}
  quickInfoTemplates={{
    header: headerTemplate.bind(),
    content: contentTemplate.bind(),
  }}
  renderCell={onCellRender.bind()}
  eventRendered={onEventRendered.bind()}
  ref={schedular_element}
  actionComplete={onActionComplete.bind()}
  headerIndentTemplate={headerIndentTemplate.bind()}
  rowAutoHeight={true}
  timeScale={{
    enable: true,
    interval: 60,
    slotCount: 60 / timeInterval,
    majorSlotTemplate: majorSlotTemplate.bind(),
    minorSlotTemplate: minorSlotTemplate.bind(),
  }}
  popupOpen={popUpHandler.bind()}
  group={{ byDate: true, resources: ['Doctors'] }}
  selectedDate={startDate}
>
  <ResourcesDirective>
    <ResourceDirective
      field="Doctor"
      name="Doctors"
      dataSource={
        selectedDoctorList.length > 0
          ? filteredDoctorListSchedulerOrDefault()
          : doctorListScheduler
      }
      textField={'resource'}
      idField={'resource'}
      allowMultiple={true}
    ></ResourceDirective>
  </ResourcesDirective>

  <Inject
    services={[
      Day,
      Week,
      WorkWeek,
      Month,
      TimelineMonth,
      Year,
      Resize,
      DragAndDrop,
    ]}
  />
  <ViewsDirective>
    <ViewDirective
      option="Day"
      endHour="24:00"
      startHour="08:00"
      interval={dateInterval}
      eventTemplate={eventTemplate.bind()}
    />
    <ViewDirective option="Week" startHour="08:00" endHour="24:00" />
    <ViewDirective
      option="WorkWeek"
      startHour="08:00"
      endHour="24:00"
    />
    <ViewDirective option="Month" />
    <ViewDirective option="TimelineMonth" />
    <ViewDirective option="Year" />
  </ViewsDirective>
</ScheduleComponent>

关闭按钮无效示意图:
关闭按钮无效示意图


解决方案

核心问题

  1. 函数组件中不存在this,所以this.CloseQuickInfoPopup()调用无效。
  2. Syncfusion React Schedule组件的弹窗关闭方法为小驼峰命名的closeQuickInfoPopup,而非大写开头。
  3. 需通过组件ref获取实例后才能调用内部方法。

具体修改步骤

1. 确保ref正确初始化

如果还没创建ref,用useRef初始化:

import { useRef } from 'react';

const schedular_element = useRef(null);

2. 修改关闭事件处理函数

更新handleCloseQuickInfoTemplate,通过ref调用正确的关闭方法:

const handleCloseQuickInfoTemplate = () => {
  // 检查ref是否已挂载实例
  if (schedular_element.current) {
    schedular_element.current.closeQuickInfoPopup();
  }
};

3. 移除模板的不必要绑定

函数组件中无需使用.bind()传递模板,直接传入函数即可:

quickInfoTemplates={{
  header: headerTemplate,
  content: contentTemplate,
}}

完整修改后的关键代码片段

import { useRef } from 'react';

const schedular_element = useRef(null);

const handleCloseQuickInfoTemplate = () => {
  if (schedular_element.current) {
    schedular_element.current.closeQuickInfoPopup();
  }
};

const headerTemplate = props => {
  return (
    <div className="e-popup-header">
      <div className="e-header-icon-wrapper">
        {/* 保留其他按钮代码 */}
        <button
          className="e-close e-control e-btn e-lib e-flat e-round e-small e-icon-btn"
          title="Close"
          onClick={handleCloseQuickInfoTemplate}
        >
          <span className="e-btn-icon e-icons e-close-icon"></span>
        </button>
      </div>
      {/* 保留其他头部内容 */}
    </div>
  );
};

// Schedule组件部分
<ScheduleComponent
  ref={schedular_element}
  // 保留其他props
  quickInfoTemplates={{
    header: headerTemplate,
    content: contentTemplate,
  }}
>
  {/* 保留子组件 */}
</ScheduleComponent>

内容的提问来源于stack exchange,提问作者Fatt Sky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:15:40