ダイナミックライブスワイヤーリスナー


課題:私たちは、1つのページにカードとして表示されるアイテムの異常に長いリストを持っています.我々は、これらのアイテムを更新するためのモーダルを使用しています.保存では、私たちは、その特定のカードを再レンダリングするだけです.我々は、リスト全体(親コンポーネントを再レンダリングする必要はありません)も必要ありません.
ここではいくつかのLiveWireコンポーネントがあります.
  • インデックスコンポーネントは、Aを使用して$項目のリストをホストし、各カード
  • の横にある編集ボタンを表示します
  • $ itemを渡し、$ item情報をカードに表示し、最後のレンダリング
  • のタイムスタンプを表示するカードコンポーネント
  • Editコンポーネントは、トリガされたときに$ itemを更新し、$ itemが保存されたときに変更イベントを発行します.

  • アプリ


    インデックスコンポーネントコード
    class Index extends Component
    {
        public $tasks;
    
        public function render()
        {
            $this->tasks = Task::all();
            return view('livewire.index');
        }
    }
    

    インデックスコンポーネントブレード
    <div class="py-10 w-full flex
        justify-center min-h-screen items-center
        bg-black text-white
        text-sm"
        <div class="w-full">
            @foreach($tasks as $task)
                <div wire:key="task-{{$loop->index}}">
                    <livewire:task.card :task="$task"/>
                    <button 
           id="complete-{{$loop->index}}"
           wire:click="$emitTo('task.edit', 'show', {{$task->id}})"> 
                       Edit
                     </button>
                </div>
            @endforeach
        </div>
        <livewire:task.edit />
    </div>
    

    編集コンポーネントコード
    class Edit extends Component
    {
        protected $listeners = ['show'];
        public $task;
        public $showing = false;
    
        protected $rules = [
            'task.status' => 'required',
            'task.name' => 'required|string|max:255'
        ];
    
        public function show(Task $task){
            $this->task = $task;
            $this->showing = true;
        }
    
        public function render(){
            return view('livewire.task.edit');
        }
    
        public function save(){
            $this->validate();
            $this->task->save();
            $this->showing = false;
    
            //tell card to refresh
            $this->emit('update-task-' . $this->task->id);
        }
    }
    

    編集コンポーネントブレード
    <div class="{{$showing? '' : 'hidden'}}"
        wire:click="$set('showing',false)">
        @if($task)
         <form wire:click.stop>
            <div>
                Task
                <input type="text" wire:model="task.name">
            </div>
            <div>Status
                <select wire:model="task.status">
                 <option value="Delayed">Delay</option>
                 <option value="Completed">Complete</option>
                 <option value="Pending">Not Started</option>
                 <option value="Canceled">Cancel</option>
                </select>
            </div>
            <div class="w-full text-right">
                <button 
                wire:click.prevent="$set('showing', false)"
                >
                Cancel
            </button>
            <button wire:click.prevent="save">
              Save
            </button>
            </div>
         </form>
        @endif
    </div>
    

    ダイナミックライブスワイヤーリスナー
    上記のコードでは何も変わったことがありませんが、Images Hide/Showはかなり標準であり、エディットボタンによってエディットコンポーネントに固有のタスクが設定され、モードを非表示にするイベントが発生します.簡潔に私はテール風クラスを削除したので、これは少し奇妙に見えるが、それは動作します.
    代わりにAlpinejsを使用する代わりに私は標準的なブレード/LiveWireと行った.上記のコードスニペットに注目したい部分は、「編集」コンポーネントの「保存」機能の最後の行です.
    $this->emit('update-task-' . $this->task->id);
    
    ここでは、この$ taskに非常に特有のイベントを発します.それでは、カードコンポーネントの後ろのコードを見てみましょう.
    class Card extends Component
    {
        public $listeners = []; // must be public!
        public $task;
    
        public function mount($task){
          // add listener specific to this task only.
          $this->listeners =["update-task-" . $task->id =>"updateTask"];  
        }
    
        public function updateTask(){
            // calling this triggers render, 
            // no code needed here
        }
    
        public function render(){
            return view('livewire.task.card');
        }
    }
    
    ここでは$ task -> id特有のリスナーを追加し、空の関数を指します.さて、$ taskを編集して保存すると、このカードインスタンスだけがその特定のイベントを待機し、このカードだけが更新されます.
    このプロジェクトのソースコードを見つけることができます