0

我正在尝试在选中和取消选中复选框时更新总数(以防用户改变主意并且不再需要该项目)。但我不确定如何获得分配给每个玩具的实际价值。例如:如果用户选择玩具 1 和 3,他们应该会看到:您订购了玩具 1、玩具 3,您的总金额为 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}
4

2 回答 2

0

隔离每个玩具价格的最佳方法是将您的玩具数组制作成一组对象,其中“名称”是一个键值对,另一个是价格。对于操纵数据,如果每个玩具都有一个 id 会很有帮助,并且我已经为每个玩具添加了一个“选定”布尔值,如果它们被添加或从“玩具列表”中删除,它就会更新。我还添加了一个“总计”变量来保存所选玩具价格的总和。

我已经玩过你的代码来完成这项工作。我使用了按钮而不是复选框,但你可以用任何你喜欢的方式来做。所以试试这个代码,它应该做你想做的事。

<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}
于 2020-04-08T10:32:45.183 回答
0

好的,首先您应该将 toynames 数组分成名称和值的数组。然后你应该绑定到输入的选中属性。

为了向用户显示当前状态,我们需要一个响应式声明。让我们称之为总。它包含两个功能。第一个返回所选名称的数组,第二个返回所选值的总和。

两者都通过查看 toylist 数组中对象的选定属性来工作。由于我们绑定了 checked 属性,这会更新。我为你创建了一个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}

编辑: 这是具有更经典语法的总函数:

  $: 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>
于 2020-04-08T10:41:37.750 回答