Javascript 苗条:改变太晚了

Javascript 苗条:改变太晚了,javascript,svelte,Javascript,Svelte,我有一个小巧的应用程序,其中包含: 用于选择要查看的图表(饼图/条形图/日历)的下拉列表 带有要包含在图表中的变量的复选框面板。(不同的图表有不同的可用变量) 一个函数,它只为所选变量过滤我的数据,然后将数据传递到图表 可以在此处运行的完整代码: <script> let rawData = { LevelTracker: [{ text: "headache" }, { text: "pain" }], EventType

我有一个小巧的应用程序,其中包含:

  • 用于选择要查看的图表(饼图/条形图/日历)的下拉列表
  • 带有要包含在图表中的变量的复选框面板。(不同的图表有不同的可用变量)
  • 一个函数,它只为所选变量过滤我的数据,然后将数据传递到图表
  • 可以在此处运行的完整代码:

    <script>
      let rawData = {
        LevelTracker: [{ text: "headache" }, { text: "pain" }],
        EventType: [{ text: "coffee" }, { text: "aspirin" }],
        Event: [
          { time: 1500000000, text: "coffee" },
          { time: 1500030000, text: "aspirin" },
          { time: 1500230000, text: "coffee" },
          // etc....
        ],
        LevelChange: [
          { time: 1500000000, text: "headache", level: 2 },
          { time: 1500030000, text: "headache", level: 3 },
          { time: 1500230000, text: "pain", level: 2 },
          // etc....
        ],
      };
    
      $: availableLTs = rawData.LevelTracker.map((e) => e.text);
      $: availableETs = rawData.EventType.map((e) => e.text);
    
      let schemas = [
        {
          name: "byTimeOfDay",
          vars: [{ name: "X", et: true, lt: true }],
        },
        {
          name: "lagBarChart",
          vars: [
            { name: "X", min: 1, et: true, lt: false },
            { name: "Y", min: 1, max: 1, lt: true, et: true },
          ],
        },
        {
          name: "calendar",
          vars: [{ name: "X", et: true, lt: true }],
        },
      ];
      let chartsMap = {};
      for (let schema of schemas) {
        chartsMap[schema.name] = schema;
      }
      //let selectedChart = "lagBarChart";
      //let selectedChart = "byTimeOfDay";
      let selectedChart = "calendar";
    
      function getInitSelectedVars(schemaVars) {
        let selection = {};
        for (let varSchema of schemaVars) {
          selection[varSchema.name] = { ets: [], lts: [] };
        }
        return selection;
      }
    
      function initSelectedVars() {
        console.log("in initSelectedVars");
        selectedVars = getInitSelectedVars(schemaVars);
      }
    
      function makeChartData({ selectedVars, rawData }) {
        console.log("in makeChartData");
        for (let [key, value] of Object.entries(selectedVars)) {
          // TODO: we filter rawData for just the selected vars, and return that data...
        }
      }
    
      // this will be passed to the chart component
      $: chartData = makeChartData({
        selectedVars,
        rawData,
      });
    
      $: schemaVars = chartsMap[selectedChart].vars;
    
      $: selectedVars = selectedVars || getInitSelectedVars(schemaVars);
    </script>
    
    <main>
      <h2>Select chart type</h2>
      <select bind:value={selectedChart} on:change={initSelectedVars}>
        {#each schemas as chart}
          <option value={chart.name}>
            {chart.name}
          </option>
        {/each}
      </select>
    
      <h2>Select your vars</h2>
    
      {#each schemaVars as schemaVar}
        <h3>
          {schemaVar.name}
        </h3>
        {#if schemaVar.lt}
          {#each availableLTs as ele}
            <div class="form-check">
              <label>
                <input
                  type="checkbox"
                  class="form-check-input"
                  bind:group={selectedVars[schemaVar.name].lts}
                  value={ele}
                />
                {ele}
              </label>
            </div>
          {/each}
        {/if}
        {#if schemaVar.et}
          {#each availableETs as ele}
            <div class="form-check">
              <label>
                <input
                  type="checkbox"
                  class="form-check-input"
                  bind:group={selectedVars[schemaVar.name].ets}
                  value={ele}
                />
                {ele}
              </label>
            </div>
          {/each}
        {/if}
      {/each}
    
      <!-- then we display the selected chart, like:
         <calendar {chartData} />
       -->
    </main>
    
    <style>
    </style>
    
    
    我认为on:change函数只有在
    selectedVars
    被更改后才能运行,所以为时已晚


    有什么建议吗?我的代码如下。

    您确定错误发生在
    makeChartData
    函数中吗?
    可能是这一行:
    bind:group={selectedVars[schemaVar.name].lts}

    我还没有完全理解您的代码,但是应该可以使用被动语句将
    selectedVars
    的值更改为所需的值。因此,我认为您不需要on:change处理程序

    编辑:
    我想你想要这样的东西:

    好的,这很有道理,谢谢!
    Uncaught (in promise) TypeError: Cannot read property 'lts' of undefined
        at Object.mount [as m] (Debug.svelte:101)
        at Object.mount [as m] (Debug.svelte:95)
        at Object.mount [as m] (Debug.svelte:109)
        at Object.update [as p] (Debug.svelte:90)
        at update (index.mjs:764)
        at flush (index.mjs:732)