Svelte обращается к переменной хранилища в теге сценария дочернего компонента - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть приложение Svelte & Sapper, в котором я использую доступное для записи хранилище Svelte для установки переменной с начальным значением пустой строки:

import { writable } from 'svelte/store';
export let dbLeaveYear = writable('');

В моем файле Index.svelte я импортирую это и затем вычисляем значение этой переменной и устанавливаем его (я делаю это в функции onMount `` `Index.svelte, если это важно):

<script>
  import {dbLeaveYear} from "../stores/store.js"

  function getCurrentLeaveYear() {
    const today = new Date();
    const currYear = today.getFullYear();
    const twoDigitYear = currYear.toString().slice(-2);
    const cutoffDate = `${twoDigitYear}-04-01`
    const result = compareAsc(today, new Date(cutoffDate));
    if (result === -1) {
      $dbLeaveYear = `${parseInt(twoDigitYear, 10) - 1}${twoDigitYear}`;
    } else {
      $dbLeaveYear = `${twoDigitYear}${parseInt(twoDigitYear, 10) + 1}`;
    }
  }

  onMount(() => {
    getCurrentLeaveYear();
  });
</script>

У меня есть дочерний компонент отрисовано в Index.svelte

<Calendar />

Внутри дочернего компонента Calendar Я импортирую переменную и пытаюсь получить к ней доступ для выполнения преобразования, но я получаю ошибки, что она по-прежнему пуста - она ​​выглядит не выбирая присвоение из Index.svelte:

<script>
  import {dbLeaveYear} from "../stores/store.js"
  const calStart = $dbLeaveYear.slice(0, 2)
</script>

Однако, если я использую значение в элементе HTML в том же дочернем компоненте Календаря с <p>{$dbLeaveYear}</p>, оно заполняется значением из расчета в Index.svelte.

Как получить доступ к переменной хранилища внутри тега <script> дочернего компонента? Это вообще возможно? Я пробовал ассигновать в onMount, я пробовал присваивать в функции - кажется, ничего не работает, и всегда говорится, что $dbLeaveYear - пустая строка.

Мне нужно, чтобы значение было Dynami c как значение года отпуска.

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

Ответ здесь - это сочетание предварительной загрузки Sapper и возможности экспорта функции из магазина.

в store.js экспорт доступного для записи хранилища для нужной вам переменной, а также функции, которая сработает значение и установите доступное для записи хранилище:

export let dbLeaveYear = writable('');

export function getCurrentLeaveYear() {
  const today = new Date();
  const currYear = today.getFullYear();
  const twoDigitYear = currYear.toString().slice(-2);
  const cutoffDate = `${twoDigitYear}-04-01`
  const result = compareAsc(today, new Date(cutoffDate));
  if (result === -1) {
    dbLeaveYear.set(`${parseInt(twoDigitYear, 10) - 1}${twoDigitYear}`);
  } else {
    dbLeaveYear.set(`${twoDigitYear}${parseInt(twoDigitYear, 10) + 1}`);
  }
}

В файле .svelte верхнего уровня используйте функцию preload() Саппера внутри тега сценария "module", чтобы вызвать функцию, которая будет работать со значением и установите доступное для записи хранилище:

<script context="module">
  import {getCurrentLeaveYear} from '../stores/store'
  export async function preload() {
        getCurrentLeaveYear();
  }
</script>

А затем в файле компонента .svelte вы можете импортировать переменную хранилища, и, поскольку она была предварительно загружена, она будет доступна в теге <script>:

<script>
  import {dbLeaveYear} from '../stores/store'

  $: startDate = `20${$dbLeaveYear.slice(0, 2)}`
  $: endDate = `20${$dbLeaveYear.slice(-2)}`
</script>
0 голосов
/ 15 апреля 2020

Прежде чем углубиться в проблему, позвольте мне сказать, что вам не следует напрямую изменять переменную хранилища, а использовать предоставленный метод set или update. Это позволяет избежать трудных для отладки ошибок:

  if (result === -1) {
      dbLeaveYear.set(() => `${parseInt(twoDigitYear, 10) - 1}${twoDigitYear}`);
    } else {
      dbLeaveYear.set(`${twoDigitYear}${parseInt(twoDigitYear, 10) + 1}`);
    }

При этом проблема заключается в том, что ваша автоматическая подписка на магазин не идеальна для вашего использования. дело. Для этого вам необходимо использовать свойство подписки:

<script>
  import { dbLeaveYear } from "../stores/store.js"
  import { onDestroy, onMount } from "svelte"

  let yearValue;
  // Needed to avoid memory leaks
  let unsubscribe

  onMount(() => {
    unsubscribe = dbLeaveYear.subscribe(value => yearValue = value.slice(0, 2));
  })

  onDestroy(unsubscribe);
</script>

Еще одна вещь, которая может вызвать вашу проблему, - это состояние гонки. Таким образом, обновление от родительского компонента не завершается, когда дочерний рендеринг. Затем вам нужно будет добавить проверку работоспособности в дочернем компоненте рендеринга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...