【问题标题】:load data after the page load in livewire在 livewire 中加载页面后加载数据
【发布时间】:2021-08-05 17:09:25
【问题描述】:

在视图中,我有一个 livewire 组件,它从 api 接收硬币列表并显示在表格内。现在我希望页面先加载,然后加载我的组件并显示硬币列表。我该怎么做做这个?我的代码是在页面加载之前接收数据

namespace App\Http\Livewire\Backend\Crypto;

use Livewire\Component;

class Cryptolist extends Component
{
    public function render()
    {
        try {
            $api = new \Binance\API('api','secret');
            $prices = $api->coins();
            $one = json_encode($prices, true);

            $coins = json_decode($one , true);
            return view('livewire.backend.crypto.cryptolist')->with('coins' , $coins);
        }catch(\Exception $e)
        {
            return view('wrong')->with('e' , $e);
        }
    }
}

这是视图

@extends('backend.layouts.app')

@section('title', __('User Management'))

@section('breadcrumb-links')
    @include('backend.auth.user.includes.breadcrumb-links')
@endsection

@section('content')
    <div class="components">
        <div class="card card-bordered">
            <div class="card-inner">
                <livewire:backend.crypto.cryptolist />
            </div>
        </div>
        <!-- .card-preview -->
    </div>
    </div>
@endsection

这是显示数据的组件:

<div wire:ignore wire:init="init">
    <div id="loadesh1">
    <table class="datatable-init nk-tb-list nk-tb-ulist" data-auto-responsive="false">
        <thead>
        <tr class="nk-tb-item nk-tb-head">
            <th class="nk-tb-col"><span class="sub-text">name</span></th>
            <th class="nk-tb-col tb-col-mb"><span class="sub-text">balance</span></th>
        </tr>
        </thead>
        <tbody>
        @foreach ($coins as $item => $value)
            <tr class="nk-tb-item">
                <td class="nk-tb-col">
                    <div class="user-card">
                        <div class="user-avatar d-none d-sm-flex">

                            @if(file_exists(public_path() . '/img/crypto/'.strtolower($value['coin'].".svg")))
                                <img style="border-radius: 0" src="{{asset('/img/crypto/'.strtolower($value['coin']))}}.svg" class="img-fluid" alt="">
                            @else
                                <img style="border-radius: 0" src="https://demo.rayanscript.ir/-/vendor/cryptocurrency-icons/32/color/noimage.png" class="img-fluid" alt="">
                            @endif

                        </div>
                        <div class="user-info">
                            <span class="tb-lead english" style="font-weight: bolder">{{$value['name']}}</span>
                            <span class="english">{{$value['coin']}}</span>
                        </div>
                    </div>
                </td>
                <td class="nk-tb-col tb-col-mb" data-order="{{$value['coin']}}">
                    <div class="btn-group" aria-label="Basic example">
                        <button type="button" class="btn btn-sm btn-dim btn-light" wire:click="getBalance('{{$value['coin']}}')">
                            <div wire:loading wire:target="getBalance('{{$value['coin']}}')">
                                <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
                            </div>
                            <span class="w-120px" id="coin-{{$value['coin']}}">get balance</span>
                        </button>
                        <button type="button" class="btn btn-sm btn-dim btn-primary">add coin</button>
                    </div>
                </td>
            </tr><!-- .nk-tb-item  -->
        @endforeach
        </tbody>
    </table>
    </div>
    </div>
</div>

【问题讨论】:

    标签: laravel laravel-livewire


    【解决方案1】:

    Livewire 中有一个名为 wire:init 的指令。这接受组件中的一个方法,该方法在第一次初始渲染后运行。

    在你的类中声明一个属性来决定你是否应该加载数据。默认将其设置为 false,并在初始化时调用的方法中将其设置为 true。

    请谨慎将其他属性设置为您的视图仍然在没有数据的情况下呈现的状态,因为您看到下面的代码在初始加载之前设置了一个空数组。

    class Cryptolist extends Component
    {
        public bool $loadData = false;
    
        public function init()
        {
            $this->loadData = true;
        }
    
        public function render()
        {
            try {
                if ($this->loadData) {
                    $api = new \Binance\API('api','secret');
                    $prices = $api->coins();
                    $one = json_encode($prices, true);
    
                    $coins = json_decode($one , true);
                } else {
                    $coins = [];
                }
                return view('livewire.backend.crypto.cryptolist')->with('coins' , $coins);
            }catch(\Exception $e)
            {
                return view('wrong')->with('e' , $e);
            }
        }
    }
    

    然后在刀片视图的根元素中,放入

    wire:init="init"
    

    https://laravel-livewire.com/docs/2.x/defer-loading


    在编辑后看到您的视图,并且您的 wire:ignore 有问题 - 以下是解决此问题的方法:将您的表和应该被忽略的代码包装在 @if ($loadData) 的条件内。这样,Livewire 组件可以在加载数据后重新渲染和推送表格,并在加载数据之前显示加载文本。

    <div wire:init="init">
        @if ($loadData)
            <div id="loadesh1" wire:ignore>
                <table class="datatable-init nk-tb-list nk-tb-ulist" data-auto-responsive="false">
                    <!-- Rest of your table -->
                </table>
            </div>
        @else
            Loading data...
        @endif
    </div>
    

    【讨论】:

    • 我写了这段代码,但是加载页面后,什么也没有发生,也没有加载
    • 在检查元素和网络选项卡中,我注意到信息已收到,但表格中没有显示任何内容
    • 您添加了wire:init 吗?听起来你没有。如果是的话,你把它放在哪里了?
    • 是的,我添加了它,它可以工作,因为我在网络选项卡中看到发送了请求并收到了响应,但问题是表格中没有显示信息。我将它添加到根元素
    • 您使用wire:ignore 明确告诉 Livewire 忽略视图的更改,因此 Livewire 不会在其中进行任何 dom-diffing。删除 wire:ignore 即可。另外需要注意的是,您的&lt;tr class="nk-tb-item"&gt; 上应该有wire:key,使其成为&lt;tr class="nk-tb-item" wire:key="coin-{{ $loop-&gt;index }}"&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    相关资源
    最近更新 更多