Laravel Livewire:Foreach 循环中的组件。按钮单击显示在所有项目上而不是单个项目
Laravel Livewire: Component in Foreach loop. Button Click shows on all items instead of Single item
我需要一些有关 Livewire Click 功能和将组件加载到 foreach 循环的帮助。
当我点击播放按钮时,该组件显示在循环中的所有项目中。但我希望它只显示在单击按钮的这一项中。
Screenshot of issue
希望有人能帮我解决这个问题。
非常感谢。
搜索-video.blade.php
@foreach ($searchResults as $item)
<div class="w-full mx-auto border rounded-md border-gray-300 shadow">
...
<div class="px-4">
<div class="mb-4 flex-1 space-y-4 py-1">
<h2 class="text-xl font-semibold overflow-ellipsis overflow-hidden">{{ $item['title'] }}
</h2>
<div class="space-y-2">
<p>
...
</p>
</div>
</div>
<div class="flex flex-wrap py-4">
<!-- Livewire Audio Player Component here -->
<div class="w-full">
<livewire:audio-player :wire:key="$item['id']">
</div>
<div wire:click="openPlayer('{{ $item['id'] }}')"
class="cursor-pointer border rounded font-semibold bg-blue-300 border-blue-600 px-4 py-2 mr-2 text-blue-600">
Play</div>
...
</div>
</div>
</div>
@endforeach
SearchVideo.php
class SearchVideo extends Component
{
....
public function loadSearchResults()
{
...
}
public function openPlayer($vid)
{
$this->emit('showPlayer', $vid)->to('audio-player');
}
public function closePlayer()
{
$this->emit('closePlayer')->to('audio-player');
}
public function render()
{
return view('livewire.search-video');
}
}
音频-player.blade.php
<div>
@isset($showPlayer)
player here {{ $videoId }}
@endif
</div>
AudioPlayer.php
class AudioPlayer extends Component
{
public $showPlayer;
public $videoId;
protected $listeners = ['showPlayer' => 'openPlayer', 'closePlayer' => 'closePlayer'];
public function openPlayer($vid)
{
$this->showPlayer = true;
$this->videoId = $vid;
}
public function closePlayer()
{
unset($this->showPlayer);
}
public function hydrate()
{
$this->dispatchBrowserEvent('contentChanged');
}
public function render()
{
return view('livewire.audio-player');
}
}
您需要能够确定音频播放器放置在哪个卡中。
首先在您的 AudioPlayer 组件中接受一个参数,该参数是视频的 ID - 将从您的搜索中传递。
在您的 AudioPlayer 组件中,添加一个 mount()
方法,您可以在其中接收一个可选参数 $showVideoId
。这意味着我们还必须将其声明为 public 属性.
public $showVideoId;
public function mount($showVideoId = null)
{
$this->showVideoId = $showVideoId;
}
接下来,我们需要从您的搜索组件中传入它,
<livewire:audio-player :showVideoId="$item['id']" :wire:key="$item['id']" />
然后,更新您的 openPlayer()
方法来检查我们尝试打开的播放器是否与 $showVideoId
相同(或者 null
如果您不传入该可选参数,用于在页面上使用此组件一次而不是多次)。
这里我们检查 $showVideoId
是否为空,或者如果它不为空,它必须匹配 $videoId
.
public function openPlayer($vid)
{
$this->videoId = $vid;
if ($this->showVideoId === null || $this->showVideoId === $this->videoId) {
$this->showPlayer = true;
}
}
我注意到的另一件事是,循环中的第一个元素应该有一个 wire:key
。
<div class="w-full mx-auto border rounded-md border-gray-300 shadow" wire:key="search-{{ $loop->index }}">
如果您的 seach-video.blade.php
视图以 @foreach
开头,那么您应该将整个组件包装在 <div>
.
中
我需要一些有关 Livewire Click 功能和将组件加载到 foreach 循环的帮助。
当我点击播放按钮时,该组件显示在循环中的所有项目中。但我希望它只显示在单击按钮的这一项中。
Screenshot of issue
希望有人能帮我解决这个问题。
非常感谢。
搜索-video.blade.php
@foreach ($searchResults as $item)
<div class="w-full mx-auto border rounded-md border-gray-300 shadow">
...
<div class="px-4">
<div class="mb-4 flex-1 space-y-4 py-1">
<h2 class="text-xl font-semibold overflow-ellipsis overflow-hidden">{{ $item['title'] }}
</h2>
<div class="space-y-2">
<p>
...
</p>
</div>
</div>
<div class="flex flex-wrap py-4">
<!-- Livewire Audio Player Component here -->
<div class="w-full">
<livewire:audio-player :wire:key="$item['id']">
</div>
<div wire:click="openPlayer('{{ $item['id'] }}')"
class="cursor-pointer border rounded font-semibold bg-blue-300 border-blue-600 px-4 py-2 mr-2 text-blue-600">
Play</div>
...
</div>
</div>
</div>
@endforeach
SearchVideo.php
class SearchVideo extends Component
{
....
public function loadSearchResults()
{
...
}
public function openPlayer($vid)
{
$this->emit('showPlayer', $vid)->to('audio-player');
}
public function closePlayer()
{
$this->emit('closePlayer')->to('audio-player');
}
public function render()
{
return view('livewire.search-video');
}
}
音频-player.blade.php
<div>
@isset($showPlayer)
player here {{ $videoId }}
@endif
</div>
AudioPlayer.php
class AudioPlayer extends Component
{
public $showPlayer;
public $videoId;
protected $listeners = ['showPlayer' => 'openPlayer', 'closePlayer' => 'closePlayer'];
public function openPlayer($vid)
{
$this->showPlayer = true;
$this->videoId = $vid;
}
public function closePlayer()
{
unset($this->showPlayer);
}
public function hydrate()
{
$this->dispatchBrowserEvent('contentChanged');
}
public function render()
{
return view('livewire.audio-player');
}
}
您需要能够确定音频播放器放置在哪个卡中。
首先在您的 AudioPlayer 组件中接受一个参数,该参数是视频的 ID - 将从您的搜索中传递。
在您的 AudioPlayer 组件中,添加一个 mount()
方法,您可以在其中接收一个可选参数 $showVideoId
。这意味着我们还必须将其声明为 public 属性.
public $showVideoId;
public function mount($showVideoId = null)
{
$this->showVideoId = $showVideoId;
}
接下来,我们需要从您的搜索组件中传入它,
<livewire:audio-player :showVideoId="$item['id']" :wire:key="$item['id']" />
然后,更新您的 openPlayer()
方法来检查我们尝试打开的播放器是否与 $showVideoId
相同(或者 null
如果您不传入该可选参数,用于在页面上使用此组件一次而不是多次)。
这里我们检查 $showVideoId
是否为空,或者如果它不为空,它必须匹配 $videoId
.
public function openPlayer($vid)
{
$this->videoId = $vid;
if ($this->showVideoId === null || $this->showVideoId === $this->videoId) {
$this->showPlayer = true;
}
}
我注意到的另一件事是,循环中的第一个元素应该有一个 wire:key
。
<div class="w-full mx-auto border rounded-md border-gray-300 shadow" wire:key="search-{{ $loop->index }}">
如果您的 seach-video.blade.php
视图以 @foreach
开头,那么您应该将整个组件包装在 <div>
.