Livewire 更新 API 调用歌曲经过的秒数

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

大家好! 我使用 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">

但运气不佳...

javascript php laravel laravel-livewire
1个回答
0
投票
// 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>
© www.soinside.com 2019 - 2024. All rights reserved.