我要触发wire:点击两次才能刷新页面中的数据

问题描述 投票:0回答:1

我使用 Laravel Livewire 创建了一个简单的收银系统,它具有从购物车中删除商品并重置购物车中所有商品的功能。 一开始一切都很好,但最近我遇到了一个问题,我必须单击删除或重置购物车按钮两次才能刷新它们,它实际上从第一次单击中删除,该组件似乎在之前渲染了购物车删除过程或者我不太明白。

抱歉我蹩脚的英语。

我尝试使用更新的钩子并将所有内容放入安装中,但它不起作用。 这是我的组件代码

<?php

namespace App\Http\Livewire;

use App\Models\CartStorage;
use App\Models\Category;
use App\Models\Customer;
use App\Models\Guide;
use App\Models\Package;
use App\Models\PaymentType;
use App\Models\Product;
use App\Models\Setting;
use App\Models\Treatment;
use Livewire\Component;

class CashierTreatment extends Component
{
    // protected $listeners = [];
    public $taxService, $paymentTypes, $categories, $customers;
    public $category_id, $guide_id, $customer_id;
    public $sub_total, $grand_total, $taxServiceValue, $payAmount, $change;

    public function mount()
    {
        $this->taxService   = Setting::where('id', 1)->first()->value;
        $this->paymentTypes = PaymentType::all();
        $this->categories   = Category::all();
        $this->customers    = Customer::all();
    }

    protected function updateTotal()
    {
        $this->sub_total        = 1000;
        $this->taxServiceValue  = $this->sub_total * $this->taxService / 100;
        $this->grand_total      = $this->sub_total + $this->taxServiceValue;
    }

    public function getCategory($category_id = null)
    {
        $this->category_id = $category_id;
    }

    public function addToCart($item)
    {
        Product::find($item['id'])->decrement('stock');
        CartStorage::updateOrCreate(
            ['product_id' => $item['id']],
            ['user_id' => auth()->user()->id]
        )->increment('qty');
        $this->updateTotal();
    }

    public function incrementQty($item)
    {
        $product = Product::find($item['product']['id']);
        if ($product->stock > 0) {
            $product->decrement('stock');
            CartStorage::where('product_id', $item['product']['id'])->increment('qty');
            $this->updateTotal();
        }
    }

    public function changeQty($item, $value)
    {
        $product    = Product::find($item['product']['id']);
        $baseStock  = $product->stock + $item['qty'];
        $value      = $value > 1 ? $value : 1;
        $value      = $value > $baseStock ? $baseStock : $value;
        CartStorage::where('product_id', $product->id)->update(['qty' => $value]);
        $product->update(['stock' => $baseStock - $value]);
    }

    public function decrementQty($item)
    {
        $cartItem = CartStorage::where('product_id', $item['product']['id'])->first();
        if ($cartItem->qty > 1) {
            Product::find($item['product']['id'])->increment('stock');
            $cartItem->decrement('qty');
            $this->updateTotal();
        }
    }

    // $orderNumber = sprintf('%04d', $orderNumber);

    // $uid = Carbon::now()->format("Ymd") . $orderNumber;

    public function removeFromCart($item)
    {
        Product::find($item['product']['id'])->update(['stock' => $item['product']['stock'] + $item['qty']]);
        CartStorage::where('product_id', $item['product']['id'])->delete();
        $this->updateTotal();
        $this->render();
    }

    public function resetCart()
    {
        $cartItem   = CartStorage::all();
        foreach ($cartItem as $item) {
            Product::find($item->product_id)->update(['stock' => $item->product->stock + $item->qty]);
        }
        CartStorage::truncate();
        $this->reset(['sub_total', 'grand_total', 'taxServiceValue', 'guide_id', 'customer_id', 'payAmount']);
        $this->render();
    }

    public function rightAmount()
    {
        $this->payAmount = $this->grand_total;
    }

    public function checkout()
    {
        // 
    }

    public function render()
    {
        $categories         = $this->categories;
        $guides             = Guide::where('check_in', 1)->get();
        $customers          = $this->customers;
        $paymentTypes       = $this->paymentTypes;
        $products           = Product::with('category')
            ->whereHas('CartStorage')
            ->orWhere('stock', '>', 0)
            ->when($this->category_id, function ($query) {
                $query->where('category_id', $this->category_id);
            })
            ->get();
        $cartList           = CartStorage::with(['product', 'product.category'])->get();

        return view('livewire.cashier-treatment', compact('categories', 'products', 'guides', 'customers', 'paymentTypes', 'cartList'));
    }
}

这是我的观点

<div class="flex flex-row h-screen">
    <div class="basis-3/4 h-dvh">
        <main class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
            <div class="flex items-baseline justify-between border-b border-gray-200 pb-6 pt-24">
              <h1 class="text-4xl font-bold tracking-tight text-gray-900">Treatments</h1>
      
              <div class="flex items-center">
                <a href="{{ route('kasir.dashboard.index') }}" class="rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"> 
                    <span aria-hidden="true"> &larr;</span>
                    Back to Dashboard
                </a>
              </div>
            </div>
      
            <section aria-labelledby="products-heading" class="pb-24 pt-6">
              <h2 id="products-heading" class="sr-only">Products</h2>
      
              <div class="grid grid-cols-1 gap-x-8 gap-y-10 lg:grid-cols-4">
                <!-- Filters -->
                <h3 class="sr-only">Categories</h3>
                <ul role="list" class="space-y-4 border-b border-gray-200 pb-6 text-sm font-medium text-gray-900">
                    <li class="cursor-pointer px-3.5 py-2.5 @if (!$category_id)
                        rounded-md bg-gray-400
                    @endif" wire:click="getCategory()">
                        All
                    </li>
                @foreach ($categories as $category)
                    <li class="cursor-pointer px-3.5 py-2.5 @if ($category_id == $category->id)
                        rounded-md bg-gray-400
                    @endif" wire:key="{{ $category->name }}{{ $category->id }}" wire:click="getCategory({{ $category->id }})" wire:loading.class="opacity-50">
                        {{ $category->name }}
                    </li>
                @endforeach
                </ul>
      
                <!-- Product grid -->
                <div class="lg:col-span-3">
                    <fieldset class="grid grid-cols-2 gap-4">
                        <legend class="sr-only">Delivery</legend>

                        @foreach ($products as $product)
                            <div wire:key="{{ $product->id }}" wire:click="addToCart({{ $product }})" class="cursor-pointer" wire:loading.class="opacity-50">
                                <label
                                class="flex cursor-pointer justify-between gap-4 rounded-lg border border-gray-100 bg-white p-4 text-sm font-medium shadow-sm hover:border-gray-200 has-[:checked]:border-blue-500 has-[:checked]:ring-1 has-[:checked]:ring-blue-500"
                                >
                                <div class="flex items-center gap-3">
                                  <img
                                      src="{{ asset($product->image) }}"
                                      alt="{{ $product->name }}"
                                      class="w-1/4 aspect-square rounded-lg object-cover"
                                    />
                                    <div class="w-full">
                                        <small>{{ $product->category->name }}</small>
                                        <p class="text-gray-700"><b>{{ $product->name }}</b></p>
                                        <div class="flex justify-between items-center w-full">
                                          <p class="mt-1 text-gray-900">Rp @money($product->price)</p>
                                          <p class="text-black font-bold">Stock : {{ $product->stock }}</p>
                                        </div>
                                    </div>
                                </div>
                                </label>
                            </div>
                        @endforeach

                      </fieldset>
                </div>
              </div>
            </section>
        </main>
    </div>
    <div class="basis-1/4">
        <div class="flex h-full flex-col overflow-y-scroll bg-white shadow-xl">
            <div class="flex-1 overflow-y-auto px-4 py-6 sm:px-6">
              <div class="flex items-start justify-between">
                <h2 class="text-lg font-medium text-gray-900" id="slide-over-title">Shopping cart</h2>
                <div class="ml-3 flex h-7 items-center">
                  
                </div>
              </div>

              <div class="mt-8">
                <div class="flow-root">
                  <ul role="list" class="-my-6 divide-y divide-gray-200">
                    {{-- @if ($cartList) --}}
                      @foreach ($cartList as $cartItem)
                          <li class="flex py-6" wire:key="{{ $cartItem->product->id }}">
                              <div class="ml-4 flex flex-1 flex-col">
                                <div>
                                    <div class="flex justify-between text-base font-medium text-gray-900">
                                      {{-- <small>{{ $item['treatment']['name'] }}</small> --}}
                                      <h3>
                                          <a href="#">{{ $cartItem->product->name }}</a>
                                      </h3>
                                      <p class="ml-4">Rp @money($cartItem->product->price)</p>
                                    </div>
                                    <p class="mt-1 text-sm text-gray-500">{{ $cartItem->product->category->name }}</p>
                                </div>
                                <div class="flex flex-1 items-end justify-between text-sm">
                                    {{-- <p class="text-gray-500">{{ $item['valid_period'] ? $item['valid_period']." Month(s)" : "-" }}</p> --}}
                                    <div class="mt-2">
                                      {{-- <label for="Quantity" class="sr-only"> Quantity </label> --}}
                                    
                                      <div class="flex items-center gap-1">
                                        <button type="button" wire:click="decrementQty({{ json_encode($cartItem) }})" class="size-10 leading-10 text-gray-600 transition hover:opacity-75">
                                          &minus;
                                        </button>
                                    
                                        <input
                                          type="integer"
                                          id="input{{ $cartItem->id }}"
                                          value="{{ $cartItem->qty }}"
                                          wire:change="changeQty({{ json_encode($cartItem) }}, $event.target.value)"
                                          {{-- wire:model="cartList[{{ $cartItem }}]['qty']" --}}
                                          class="h-10 w-16 rounded border-gray-200 text-center [-moz-appearance:_textfield] sm:text-sm [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none"
                                        />
                                    
                                        <button type="button" wire:click="incrementQty({{ json_encode($cartItem) }})" class="size-10 leading-10 text-gray-600 transition hover:opacity-75">
                                          &plus;
                                        </button>
                                      </div>
                                    </div>
                                    <div class="flex">
                                      <button type="button" wire:click="removeFromCart({{ json_encode($cartItem) }})" class="font-medium text-indigo-600 hover:text-indigo-500">Remove</button>
                                    </div>
                                </div>
                              </div>
                          </li>
                      @endforeach
                    {{-- @endif --}}
                  </ul>
                </div>
              </div>
            </div>

            <div class="border-t border-gray-200 px-4 py-6 sm:px-6">
              {{-- <form wire:submit="checkout"> --}}

                <div class="flex flex-row items-center justify-center gap-2">
                    <div class="basis-1/2">
                        <label for="HeadlineAct" class="block text-sm font-medium text-gray-900"> Customer </label>
                        <select id="HeadlineAct" wire:model="customer_id" class="mt-1.5 w-full rounded-lg border-gray-300 text-gray-700 sm:text-sm">
                          <option value="">Please select</option>
                          @foreach ($customers as $customer)
                                <option value="{{ $customer->id }}" wire:key="{{ $customer->name.$customer->id }}">
                                    {{ $customer->name }}
                                </option>
                          @endforeach
                        </select>
                    </div>
                    <div class="basis-1/2">
                        <label for="HeadlineAct1" class="block text-sm font-medium text-gray-900"> Guide </label>
                        <select wire:model="guide_id" id="HeadlineAct1" class="mt-1.5 w-full rounded-lg border-gray-300 text-gray-700 sm:text-sm">
                          <option value="">Please select</option>
                          @foreach ($guides as $guide)
                                <option value="{{ $guide->id }}" wire:key="{{ $guide->name.$guide->id }}">
                                    {{ $guide->name }}
                                </option>
                          @endforeach
                        </select>
                    </div>
                </div>
                <div class="mt-2">
                  <label for="amount" class="block text-sm font-medium text-gray-900"> Pay Amount </label>
                  <input
                    type="number"
                    id="amount"
                    placeholder="Rp"
                    wire:model="payAmount"
                    value="{{ $payAmount }}"
                    class="mt-1 w-full rounded-md border-gray-200 shadow-sm sm:text-sm"
                  />
              </div>

                <div class="flex justify-between text-base font-medium text-gray-900 mt-2">
                    <p>Subtotal</p>
                    <p>Rp @money($sub_total)</p>
                </div>
                <div class="flex justify-between text-base font-medium text-gray-900 mt-2">
                  <p>Tax & Services</p>
                  <p>Rp @money($taxServiceValue)</p>
                </div>
                <div class="flex justify-between text-base font-medium text-gray-900 mt-2">
                    <p>Grandtotal</p>
                    <p>Rp @money($grand_total)</p>
                </div>
                <div class="flex justify-between text-base font-medium text-gray-900 mt-2">
                  <p>Change</p>
                  <p>Rp @money($change)</p>
                </div>
                {{-- <p class="mt-0.5 text-sm text-gray-500">Refreshing page will reset all data.</p> --}}

                <span class="mt-6 inline-flex -space-x-px overflow-hidden rounded-md border bg-white shadow-sm w-full">
                    <button
                      type="reset"
                      wire:click="resetCart"
                      wire:loading.class="cursor-wait opacity-50"
                      class="inline-block w-1/3  px-5 py-1 text-sm font-medium text-white bg-red-600 shadow-sm hover:bg-red-700 focus:relative"
                    >
                      Reset Cart
                    </button>
                    <button
                      type="button"
                      wire:click="rightAmount"
                      wire:loading.class="cursor-wait opacity-50"
                      class="inline-block w-1/3  px-5 py-1 text-sm font-medium text-white bg-indigo-600 shadow-sm hover:bg-indigo-700 focus:relative"
                    >
                      Right Amount
                    </button>
                    <button
                      class="inline-block w-fit  px-5 py-1 text-sm font-medium text-white bg-green-600 shadow-sm hover:bg-green-700 focus:relative"
                    >
                      Submit Payment
                    </button>
                </span>
              {{-- </form> --}}

              {{-- <div class="mt-6 flex justify-center text-center text-sm text-gray-500">
                  <p>
                  or
                  <button type="button" wire:click="resetCart" class="font-medium text-indigo-600 hover:text-indigo-500">
                      Remove all item
                      <span aria-hidden="true"> &rarr;</span>
                  </button>
                  </p>
              </div> --}}
          </div>
      </div>
</div>

laravel
1个回答
0
投票

终于找到答案了!

通过在 foreach 内元素的唯一键末尾添加“li”,如下所示

@foreach ($cartList->sortBy('product.name') as $key => $cartItem)
                      <li class="flex py-2" wire:key="{{ $key+1 }}li">

单个组件中的键确实不能相同,即使它处于不同的迭代中:)

© www.soinside.com 2019 - 2024. All rights reserved.