Svelte - текст внутри моей кнопки не меняется

Ситуация следующая:

У меня есть несколько кнопок, которые выполняют разные асинхронные функции.

Все они кнопки прогресса

Я хочу, чтобы при нажатии кнопки менялась метка, указывающая на состояние функциональности (название функциональности, загрузка, выполнение или ошибка, если это необходимо)

Все работает нормально но текст не меняется

Примечание. На данный момент я не реализовал все четыре функции, но с одной должна работать

вот компоненты.

Компонент 1 - контейнер

<script>
  import Button from '../components/Button.svelte'
  import { cubiqSetUp } from '../../../store/store.js'
  import { fly } from 'svelte/transition'
  import URLS from '../../../api/endpoints.js'

  let loadingEffect = false
  let ButtonText = null
  async function calibrate(current) {
    console.log(current.detail)
    loadingEffect = true
    ButtonText = 'CARGANDO...'
    console.log(ButtonText)
    let { calibrateURL } = await URLS()
    await fetch(calibrateURL)
      .then(response => {
        loadingEffect = false
        ButtonText = 'LISTO'
        response.json()
        setTimeout(() => {
          ButtonText = current.detail
        }, 1500)
      })
      .catch(error => {
        ButtonText = 'ERROR'
        loadingEffect = false
        setTimeout(() => {
          ButtonText = current.detail
        }, 1500)
      })
  }
</script>

<div class="Buttons">
  <div class="Buttons-container">
    <Button
      on:active={() => console.log('Pending')}
      {loadingEffect}
      ButtonText="CUBICAR" />
    <Button
      on:active={calibrate}
      {loadingEffect}
      ButtonText="CALIBRAR"
      delay={400} />
    {#if $cubiqSetUp.print_info === 'true' && $cubiqSetUp.OCR === 'true'}
      <Button ButtonText="IMPRIMIR" delay={800} />
    {:else if $cubiqSetUp.print_info === 'true'}
      <Button ButtonText="GUARDAR" delay={800} />
      <Button ButtonText="IMPRIMIR" delay={1200} />
    {:else if $cubiqSetUp.OCR === 'true'}
      <!-- No additional buttons -->
    {:else}
      <Button ButtonText="GUARDAR" delay={800} />
    {/if}
  </div>
</div>

Компонент 1 - кнопка

<script>
  import { fly } from 'svelte/transition'
  import { createEventDispatcher } from 'svelte'

  const dispatch = createEventDispatcher()

  export let ButtonText = ''
  export let delay = 200
  export let loadingEffect = false
</script>

<div
  transition:fly={{ delay, y: 200, duration: 2000 }}
  on:click={() => dispatch('active', ButtonText)}
  class="progress-btn {loadingEffect ? 'active' : ''}">
  <div class="btn">{ButtonText}</div>
  <div class="progress" />
</div>


Буду признателен, если вы, ребята, посмотрите


person nicolasgarcia214    schedule 30.04.2020    source источник


Ответы (2)


Я предполагаю, что ваш вопрос относится конкретно к кнопке CALIBRAR, поскольку она единственная, действительно запускающая полный цикл действия / ответа.

Я не знаю, почему вы ожидаете, что текст вашей кнопки обновится, когда вы установите для него предопределенное значение:

<Button
  on:active={calibrate}
  {loadingEffect}
  ButtonText="CALIBRAR"
  delay={400} />

ButtonText в вызове вашего компонента выше является именем свойства и вообще не связано с переменной ButtonText, которую вы определяете в разделе <script>. Вы должны сделать это явно:

<Button
  on:active={calibrate}
  {loadingEffect}
  ButtonText={ButtonText}
  delay={400} />

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

<Button
  on:active={calibrate}
  {loadingEffect}
  {ButtonText}
  delay={400} />

Вам также необходимо обновить раздел скрипта, чтобы правильно инициализировать переменную ButtonText, поскольку теперь она используется для установки текста по умолчанию для вашей кнопки:

<script>
  ...
  let ButtonText = 'CALIBRAR'
  ...
</script>

Обратите внимание, что это, очевидно, действительно только для этой единственной кнопки калибровки. Если бы у вас было несколько кнопок с динамическим текстом, вам, вероятно, пришлось бы использовать массив или объект с ключом для хранения их значения по умолчанию и текущего состояния вместо одной переменной.

person Thomas Hennes    schedule 30.04.2020

Я сделал это следующим образом:

<script>
  import Button from '../components/Button.svelte'
  import { cubiqSetUp } from '../../../store/store.js'
  import { fly } from 'svelte/transition'
  import URLS from '../../../api/endpoints.js'

  let loadingEffect = [false, false, false, false]
  let ButtonText = ['CUBICAR', 'CALIBRAR', 'GUARDAR', 'IMPRIMIR']
  async function calibrate(current) {
    loadingEffect[1] = true
    ButtonText[1] = 'CARGANDO...'
    let { calibrateURL } = await URLS()
    await fetch(calibrateURL)
      .then(response => {
        loadingEffect[1] = false
        ButtonText[1] = 'LISTO'
        response.json()
        setTimeout(() => {
          ButtonText[1] = current.detail
        }, 1500)
      })
      .catch(error => {
        ButtonText[1] = 'ERROR'
        loadingEffect[1] = false
        setTimeout(() => {
          ButtonText[1] = current.detail
        }, 1500)
      })
  }

  async function cubicate(current) {
    loadingEffect[0] = true
    ButtonText[0] = 'CARGANDO...'
    let { calibrateURL } = await URLS()
    await fetch(calibrateURL)
      .then(response => {
        loadingEffect[0] = false
        ButtonText[0] = 'LISTO'
        response.json()
        setTimeout(() => {
          ButtonText[0] = current.detail
        }, 1500)
      })
      .catch(error => {
        ButtonText[0] = 'ERROR'
        loadingEffect[0] = false
        setTimeout(() => {
          ButtonText[0] = current.detail
        }, 1500)
      })
  }
</script>

<div class="Buttons">
  <div class="Buttons-container">
    <Button
      on:active={cubicate}
      loadingEffect={loadingEffect[0]}
      ButtonText={ButtonText[0]} />
    <Button
      on:active={calibrate}
      loadingEffect={loadingEffect[1]}
      ButtonText={ButtonText[1]}
      delay={400} />
    {#if $cubiqSetUp.print_info === 'true' && $cubiqSetUp.OCR === 'true'}
      <Button
        on:active={() => console.log('Pending')}
        ButtonText={ButtonText[3]}
        loadingEffect={loadingEffect[3]}
        delay={800} />
    {:else if $cubiqSetUp.print_info === 'true'}
      <Button
        on:active={() => console.log('Pending')}
        ButtonText={ButtonText[2]}
        loadingEffect={loadingEffect[2]}
        delay={800} />
      <Button
        on:active={() => console.log('Pending')}
        ButtonText={ButtonText[3]}
        loadingEffect={loadingEffect[3]}
        delay={1200} />
    {:else if $cubiqSetUp.OCR === 'true'}
      <!-- No additional buttons -->
    {:else}
      <Button
        on:active={() => console.log('Pending')}
        ButtonText={ButtonText[2]}
        loadingEffect={loadingEffect[2]}
        delay={800} />
    {/if}
  </div>
</div>

Я не уверен, что это лучшие практики, но они отлично работают.

Примечание. Мне все еще нужно реализовать остальные функции.

person nicolasgarcia214    schedule 30.04.2020
comment
Я вижу здесь много повторений, а также прямой доступ к индексам массивов вместо некоторой формы программного цикла. Я бы поместил все атрибуты, связанные с кнопкой (подмаршрут API, метка, задержка, эффект) в массив объектов, и написал бы одну функцию для обработки удаленной выборки с индексом целевой кнопки в качестве параметра (и вы могли бы передайте этот индекс в detail вашего настраиваемого события). - person Thomas Hennes; 30.04.2020
comment
В остальном функционал другой. Даже тот, которого зовут CUBICAR. Я просто копирую и вставляю ту же функцию CALIBRAR, чтобы увидеть диспетчер, и эффекты будут работать так, как я хотел. Но спасибо за совет. Я буду иметь это в виду. - person nicolasgarcia214; 01.05.2020