typescript 无法读取undefined的属性(阅读“notifyPlugins”)- chart.js

laik7k3q  于 2023-05-30  发布在  TypeScript
关注(0)|答案(1)|浏览(134)

为什么我的图表在导航离开图表页面时试图读取notifyPlugins('beforeDestroy')?
我有一个插件文件,一个svelte操作和一个主文件[ChartMetrics.svelte](在其中使用该操作)。当前的行为是图表在主页中加载完全正常,但当导航到另一个页面时,我遇到了notifyPlugins错误。我已经添加了我的项目中最相关的代码,因为整个代码库非常大,所以无法将其添加到codesandbox中。在使用chart.js之前,有人收到过notifyPlugins的这个错误吗?如果还有其他代码需要查看,请告诉我。
控制台错误:

chart.js:6171 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'notifyPlugins')
    at destroy (chart.js:6171:1)
    at Object.destroy [as d] (ChartMetrics.svelte:454:1)
    at Object.destroy [as d] (Div.svelte:127:1)
    at destroy_component (index.mjs:1974:1)
    at Object.destroy [as d] (ChartMetrics.svelte:127:1)
    at Object.destroy [as d] (ChartMetrics.svelte:535:1)
    at destroy_component (index.mjs:1974:1)
    at Object.destroy [as d] (EffectiveMaterialAssetsMetricsContainer.svelte:71:1)
    at Object.destroy [as d] (MetricWrapper.svelte:133:1)
    at Object.destroy [as d] (MetricWrapper.svelte:308:1)

chart.js(第6171行):

destroy() {
   this.notifyPlugins('beforeDestroy');
   ....
}

ChartMetrics(第454行):

d: function destroy(detaching) {
            if (detaching) detach_dev(div0);
            if_blocks[current_block_type_index].d();
            destroy_component(tooltipinfo);
            destroy_component(anchor);
            if (detaching) detach_dev(t3);
            if (detaching) detach_dev(div1);
            mounted = false;
            dispose();
        }

ChartMetrics行454(图像):

plugins.ts:

export function textPlugin(value: number, theme: Theme) {
  return {
    id: "chartTextPlugin",
    // Plugin for writing text in middle of chart
    beforeDraw: function (chart: ChartType) {
      plugin that draws some text on a chart.js chart
    },
  }
}

export function curvePlugin() {
  // Curve edges of donut
  return {
    id: "chartCurvePlugin",
    afterUpdate: function (chart: ChartType) {
      // some code to curve the edges of the chart.js chart
      }
    },
    afterDraw: function (chart: ChartType) {
      // some more code to do same as above
    },
  }
}

add-chart.ts(svelte action)

export const addChart = (node: HTMLElement, params: ChartProps): ChartGauge => {
  const text = textPlugin(params.value, params.theme)
  const curve = curvePlugin()
  const backgroundColor = mapTypeToColor(params.theme)

  return new Chart(node, {
    type: "doughnut",
    data: {
      datasets: [
        {
          //label: params.caption,
          data: [params.value, 100 - params.value],
          backgroundColor: backgroundColor,
          borderColor: ["rgba(255, 255, 255 ,1)"],
          borderWidth: 0,
        },
      ],
    },
    options: {
      rotation: -90,
      cutout: "85%",
      circumference: 180,
      radius: "85%",
      responsive: true,
      maintainAspectRatio: true,
      aspectRatio: 3,
    },
    plugins: [text, curve],
  })
}

ChartMetrics.svelte

{#if value >= 0 && value <= 100}
  <CardDiv p={4} pl={4} pr={4}>
    <div class="metrics-header">
      <h3>
        Controls -
        {#if titleUrl}
          <Anchor href={titleUrl} size={14}>{title}</Anchor>
        {:else}
          <span>{title}</span>
        {/if}
        <TooltipInfo content={tooltipContent} id="info" width="small" />
      </h3>
      <Anchor href={assuranceUrl} size={14}>View Assurance</Anchor>
    </div>
    <div class="chart">
      <canvas
        id="chart"
        data-test-id="chart"
        use:addChart={{ value, theme }}
        style="height:100%;width:100%;"
      />
    </div>
  </CardDiv>
{:else}
  <MetricsError message="Chart Metrics Widget Error: Invalid value." />
{/if}
enxuqcxy

enxuqcxy1#

你可以试试这个补丁的解决方案:在add-chart.ts中,而不是

return new Chart(node, {
.....
});

使用

const chart = new Chart(node, {
    .....
});
chart.destroy = chart.destroy.bind(chart);
return chart;

一个更苗条的习惯用法可能是

return {
   ...chart,
   destroy(){
      chart.destroy();
   }
}

但这可能需要一些打字脚本技巧来通过类型检查。

相关问题