大家好! 我使用 Livewire (PHP LARAVEL) 组件创建了一个 API 调用,该调用返回一首特定的歌曲。回报是准确的:
['song' =>[
'title'=>'....',
'artist'=>'....'.
'art'=>'....',
'seconds_elapsed'=> '....',
'seconds_total'=>'....',
]]
一切正常,我做了一个逻辑,其中父div执行“
wire:poll.{{$remainingTime}}s="fetchSongData"
”(剩余时间是秒数总和秒数之间的差异,以获取歌曲的剩余时间)
因此,每次歌曲完成时,他都会“刷新”组件并更改所有实际属性。
问题是...我想在 LIVE 中实际看到 Seconds_elapsed 的变化,因为在 API 中,它们每秒都会变化,但由于我在平均 3 分钟的“remainingTime”中调用 API 一次,因此秒数仅在以下情况下才会更新:我刷新页面。
我尝试使用wire:poll.750ms,我可以在我的终端上看到他正在显示新行:
"2024-04-12 16:27:10 ..................................................................... ~ -4s"
每一秒,但流逝的秒数保持不变。
我做了一个JavaScript来获取一次Seconds_elapsed,并开始按照他获得的秒数进行计数。当我刷新时,该值会被存储,因此它将根据刷新之前的值进行计数。 尽管这个“解决方案”似乎有效,但计数与 API 附带的 secondary_elapsed 的计时并不完全匹配。所以每次刷新页面时,秒数都会向后甚至向前移动一点。 有一种方法可以在 LIVE 秒内查看一些 Livewire 属性、方法还是我不知道?或者我需要使用Javascript?仍然使用 Javascript,它不能很好地工作,并且它会破坏我的导航项目的 Livewire 的“wire:navigate”脚本。
这是实际的代码:
class TitleSong extends Component
{
public $songTitle;
public $songArtist;
public $songImage;
public $secondsTotal;
public $secondsElapsed;
public $elementToShow;
public $remainingTime;
public function render()
{
return view('livewire.title-song');
}
public function mount()
{
$this->fetchSongData();
}
public function fetchSongData()
{
try{
$response = Http::get('myAPI');
$data = $response->json();
$this->songArtist = $data['song']['artist'];
$this->secondsElapsed = $data['song']['seconds_elapsed'];
$this->secondsTotal = $data['song']['seconds_total'];
$this->songImage = $data['song']['art'];
$this->songTitle = $data['song']['title'];
$remainingTime = $this->secondsTotal - $this->secondsElapsed;
$this->remainingTime = $remainingTime;
} catch (\Throwable $th) {
dd($th->getMessage());
}
}
}
我的组件blade.php:
<div wire:poll.{{$remainingTime}}s="fetchSongData">
@if ($elementToShow === 'songTitle')
<h1 id="songTitle" style="color: var(--quaternary-color); font-weight: 600" class="text-4xl">{{$songTitle}}</h1>
@elseif ($elementToShow === 'songArtist')
<p id="songArtist" class="mt-2 ml-1" style="color: var(--quinary-color); font-weight: 400; font-size: 15px">{{$songArtist}}</p>
@elseif ($elementToShow === 'secondsElapsed')
<span id="secondsElapsed" class="current-time">{{$secondsElapsed}}</span>
@elseif ($elementToShow === 'secondsTotal')
<span id="secondsTotal" class="total-time"> {{substr($secondsTotal, 0, 1) . ':' . substr($secondsTotal, 1, 2)}}</span>
@elseif($elementToShow === 'songImage')
<img style="position: absolute; left: 12%; top: 2%; border-radius:20px; z-index: 1" width="220px" height="200px" src="{{$songImage}}" /> alt="">
@endif
</div>
我删除了JS,因为它不完美,需要一些调整。 谢谢您阅读全部内容,如果您能提供帮助,我将不胜感激!
我尝试在“secondsElapsed”的HTML元素上使用wire:poll.750ms,我尝试使用Javascript Vanilla来计算SecondsElapsed的值(但在添加wire:navigate到导航链接时似乎会出现错误,即使有这个标签和导航链接之间没有任何关系,我什至试图询问 Livewire 开发人员,但他们不断给我简短的答案,告诉我如何使我的代码更“高效”或使用 Alpine,即使我不知道 alpine。 。 仍在使用wire:poll.750ms,我希望每毫秒刷新一次输出,但它不起作用:
<div wire:poll.{{$remainingTime}}s="fetchSongData">
这实际上是有效的。我什至尝试再次请求相同的 API,但只获取秒数,然后执行 a
<div wire:poll.750ms="fetchSecondsElapsed">
但运气不佳...
// I can't explain in details but below is an optimize code you can adopt.
class TitleSong extends Component
{
public $songTitle;
public $songArtist;
public $songImage;
public $secondsTotal;
public $secondsElapsed;
public $elementToShow;
public $remainingTime;
public function render()
{
return view('livewire.title-song');
}
public function mount()
{
$this->fetchSongData();
}
public function fetchSongData()
{
try {
$response = Http::get('myAPI');
$data = $response->json();
$this->songArtist = $data['song']['artist'];
$this->secondsElapsed = $data['song']['seconds_elapsed'];
$this->secondsTotal = $data['song']['seconds_total'];
$this->songImage = $data['song']['art'];
$this->songTitle = $data['song']['title'];
$remainingTime = $this->secondsTotal - $this->secondsElapsed;
$this->remainingTime = $remainingTime;
} catch (\Throwable $th) {
dd($th->getMessage());
}
}
public function updatedSecondsElapsed($value)
{
// Handle logic if needed when seconds elapsed is updated
}
}
// Modify your livewire code
<div wire:poll.{{$remainingTime}}s="fetchSongData">
<!-- Your existing Blade code -->
<script>
setInterval(function () {
@this.call('fetchSongData'); // Call the Livewire fetchSongData method
}, 1000); // Update every second
</script>
</div>