Добавление цен выбранных опций для флажков - Использование Svelte - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь обновить итоговые значения, поскольку флажки сняты и сняты (если пользователь передумает и больше не хочет этот элемент). Но я не уверен, как получить реальное значение, которое я присвоил каждой игрушке. Например: если пользователь выбирает игрушку 1 и 3, он должен увидеть: вы заказали игрушку Toy1, Toy3, и ваша общая сумма составляет $ 6,00. На данный момент я присвоил значения самим именам, что не то, что я хочу, а просто добавил это, чтобы показать, что я пытаюсь сделать. Это что-то еще, что я должен использовать, на самом деле выполнить операцию, чтобы получить общее количество?

<script>
        let toylist = [];
        let toynames = [
                     'Toy1 5.00',
           'Toy2 5.00',
                     'Toy3 1.00',
        ];

        function join(toylist) {
            return toylist.join(', ');
        }
</script>
    {#each toynames as toy}
        <label>
            <input type=checkbox bind:group={toylist} value={toy}> {toy}
        </label>
    {/each}

    {#if toylist.length === 0}
        <p>Pick at least one toy</p>
     {:else}
        <p>
           You ordered {toylist.join(', ')} and your total is
        </p>
    {/if}

Ответы [ 2 ]

0 голосов
/ 08 апреля 2020

Хорошо, сначала вы должны разделить массив toynames на массив имен и значений. Затем вам нужно привязать свойство selected к входу.

Чтобы отобразить текущее состояние для пользователя, нам нужно реактивное объявление. Давайте назовем это общим. Он содержит две функции. Первый возвращает массив выбранных имен, второй - сумму выбранных значений.

Обе они работают, просматривая выбранное свойство объекта в массиве списка. Это обновление связано с нашей привязкой проверенного атрибута. Я создал repl , чтобы вы могли поиграть ;-) с

<script>
    let toylist = [
        {name: "Toy", value: 5, selected: false},
        {name: "Elephant", value: 6, selected: false}, 
        {name: "Choo-Choo", value: 1, selected: false}
    ]

  $: total = {
    names: toylist.reduce((acc, cV) => {
      if (cV && cV.selected) {
        return [...acc, cV.name];
      } else return [...acc];
    }, []),
    values: toylist.reduce((acc, cV) => {
      if (cV && cV.selected) {
        return parseInt(acc) + parseInt(cV.value);
      } else return parseInt(acc);
    }, 0)
  };

</script>
    {#each toylist as {name,value, selected}}
        <label>
            <input type=checkbox bind:checked={selected} bind:value={value}> {name}
        </label>
    {/each}

    {#if toylist.length === 0}
        <p>Pick at least one toy</p>
     {:else}
        <p>
           You ordered {total.names.length < 1 ? "nothing": total.names} and your total is {total.values}
        </p>
    {/if}

EDIT: Вот общая функция с более classi c синтаксис:

  $: total = {
    names: toylist.reduce(function(acc, cV) {
      if (cV && cV.selected) {
        return [...acc, cV.name];
      } else return [...acc];
    }, []),
    values: toylist.reduce(function(acc, cV) {
      if (cV && cV.selected) {
        return parseInt(acc) + parseInt(cV.value);
      } else return parseInt(acc);
    }, 0)
  };

А здесь без? оператор:

<script>
  function renderNames() {
    if (total.names.length < 1) {
      return "nothing";
    } else {
      return total.names;
    }
  }
</script>

 <p>You ordered {renderNames()} and your total is {total.values}</p>
0 голосов
/ 08 апреля 2020

Лучший способ изолировать цену каждой игрушки - это превратить ваш массив игрушек в массив объектов, где «имя» - это одна пара ключ-значение, а цена - другая. Для манипулирования данными было бы полезно, если бы у каждой игрушки был свой идентификатор, и я добавил «выбранное» логическое значение для каждой игрушки, которая обновляется, если они добавляются или удаляются из «списка». Я также добавил переменную «total» для хранения общей цены выбранных игрушек.

Я немного поиграл с вашим кодом, чтобы сделать эту работу. Я использовал кнопки вместо флажков, но вы можете сделать это любым удобным для вас способом. Так что дайте этому коду go, и он должен делать то, что вы хотите.

<script>
  let toylist = [];
  let toys = [
        {id: 1, name: 'Toy 1', price: 5.00, selected: false},
        {id: 2, name: 'Toy 2', price: 5.00, selected: false},
        {id: 3, name: 'Toy 3', price: 1.00, selected: false}
    ];
  let total = 0.00
  function join(toy) {
        if(toy.selected === false) {
            toylist = [...toylist, toy.name]
            total = total+toy.price
            let i = toys.findIndex(t => t.id === toy.id)
            toys[i].selected = true
            toys = toys
        } else {
            total = total-toy.price
            let i = toys.findIndex(t => t.id === toy.id)
            let i2 = toylist.findIndex(t => t === toy.name)
            toylist.splice(i2, 1)
            toylist = toylist
            toys[i].selected = false
            toys = toys
        }
  }
</script>
{#each toys as toy}
    <label>
        {toy.name}: ${toy.price} <button on:click="{() => join(toy)}" value={toy.name}>{toy.selected ? 'remove' : 'add'}</button>
    </label>
{/each}

{#if toylist.length === 0}
    <p>Pick at least one toy</p>
{:else}
    <p>
        You ordered {toylist} and your total is ${total}
    </p>
{/if}
...