【问题标题】:foreach in livewire acting weirdLivewire 中的 foreach 行为怪异
【发布时间】:2021-08-29 02:05:47
【问题描述】:

我在 Livewire 组件的每个下方都有两个表, 我想要做的是当我点击其中一个角色时 第二个表(权限表)应该使用提供的角色权限刷新, 第一次和第二次点击它工作得很好,但之后权限表开始变长,一些元素开始尿布,这是我的角色控制器:

<?php
use Livewire\Component;
use Spatie\Permission\Models\Role;

class RolesTable extends Component
{   
    public $permissions;
    protected $listeners = ['refreash_permissions' => '$refresh'];
    public function render()
    {
        $roles = Role::all();
        return view('components.roles-table',compact(['roles' , $roles]));
    }
    public function get_permissions($role_id){
        $this->emitSelf('refreash_permissions');
        if($role = Role::findById($role_id)) {
            $role = Role::findById($role_id);
            $this->permissions = $role->permissions()->get();

        }

    }

}

这是我的观点:

<div class="">
    <div class="col-12 mb-3">
        <p class="mx-2 h3">Roles :</p>
        <table class="table table-hover table-inverse shadow-lg rounded-corners">
            <thead class="thead-inverse">
                <tr class="border-bottom">
                    <th class="mx-3 count">#</th>
                    <th class="mx-3  full-name" width="150px">Role Name</th>
                    <th class="mx-3 responsive-766" width="auto">Role Description</th>
                    <th class="mx-3 auctions d-flex justify-content-end mx-5"  width="auto">Actions</th>
                </tr>
                </thead>
                <tbody>
                    @foreach ($roles as $role)
                    <tr id="{{ $role->id }}" wire:click="get_permissions({{ $role->id }})" class="">
                        <td class="mx-3">{{ $loop->iteration }}</td>
                        <td class="">{{ $role->name }}</td>
                        <td id="{{ $role->description }}" class="description responsive-766">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ducimus rem porro inventore nemo ad ratione aperiam minima necessitatibus excepturi provident sunt blanditiis quis tempore, pariatur dicta quidem nesciunt beatae, quia eaque? Ut .</td>
                        <td id='{{ $role->id }}' class="auction d-flex justify-content-end">
                            @can('view_roles')
                            <a id="{{ $role->id }}" class="role_profile btn btn-inv-info btn-sm m-1"><i class="fad fa-id-card fa-lg"></i></a>
                            @endcan
                            @can('edit_roles')
                            <a id="{{ $role->id }}" class="role_edit btn btn-inv-warning btn-sm m-1"><i class="fad fa-key fa-lg"></i></a>                         
                            @endcan
                            @can('delete_roles')
                            <a id="{{ $role->id }}" class="role_remove btn btn-inv-danger btn-sm m-1"><i class="fad fa-trash fa-lg"></i></a>
                            @endcan
                        </td>
                    </tr>
                    @endforeach
                </tbody>
        </table>
    </div>
    <div class="col-12 mb-3">
        <p class="mx-2 h3">Permissions :</p>
        <table class="table table-hover table-inverse shadow-lg rounded-corners">
            <thead class="thead-inverse">
                <tr class="border-bottom">
                    <th class="mx-3 count">#</th>
                    <th class="mx-3  full-name" width="150px">Permission Name</th>
                    <th class="mx-3 responsive-766" width="auto">Permission Description</th>
                    <th class="mx-3 auctions d-flex justify-content-end mx-5"  width="auto">Actions</th>
                </tr>
                </thead>
                <tbody>
                    @if ($permissions)
                    @foreach ($permissions as $permission)
                    <tr id="{{ $permission->id }}" class="">
                        <td class="mx-3">{{ $loop->iteration }}</td>
                        <td class="">{{ $permission->name }}</td>
                        <td id="{{ $permission->description }}" class="description responsive-766">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ducimus rem porro inventore nemo ad ratione aperiam minima necessitatibus excepturi provident sunt blanditiis quis tempore, pariatur dicta quidem nesciunt beatae, quia eaque? Ut .</td>
                        <td id='{{ $permission->id }}' class="auction d-flex justify-content-end">
                            @can('view_roles')
                            <a id="{{ $permission->id }}" class="permission_profile btn btn-inv-info btn-sm m-1"><i class="fad fa-id-card fa-lg"></i></a>
                            @endcan
                            @can('edit_roles')
                            <a id="{{ $permission->id }}" class="permission_edit btn btn-inv-warning btn-sm m-1"><i class="fad fa-key fa-lg"></i></a>                         
                            @endcan
                            @can('delete_roles')
                            <a id="{{ $permission->id }}" class="permission_remove btn btn-inv-danger btn-sm m-1"><i class="fad fa-trash fa-lg"></i></a>
                            @endcan
                        </td>
                    </tr>
                    @endforeach   
                    @else
                    <tfoot>
                        <tr>
                            <td class="auto"></td>
                            <td class="auto"></td>
                            <td class="auto"></td>
                            <td width="auto d-flex justify-content-end text-center">there is nothing to show</td>
                            <td class="auto"></td>
                            <td class="auto"></td>
                            <td class="auto"></td>
                        </tr>
                    </tfoot>   
                    @endif
                    
                </tbody>
        </table>
</div>
</div>

这也是一些截图: this before any click this after one or two clicks 在任何点击之后,表格变成链接: this when the thing become super weird 任何建议,我将不胜感激。

【问题讨论】:

    标签: php html laravel foreach laravel-livewire


    【解决方案1】:

    在你的渲染方法中,你有一个紧凑的数组:

    public function render()
    {
        $roles = Role::all();
        return view('components.roles-table',compact(['roles' , $roles]));
    }
    

    理想情况下,您应该将compact('roles') 传递给该方法。

    其次,您在 get_permissions 方法中执行以下操作

    public function get_permissions($role_id)
    {
        $this->emitSelf('refreash_permissions');
        if($role = Role::findById($role_id)) {
            $role = Role::findById($role_id);
            $this->permissions = $role->permissions()->get();
        }
    }
    

    您正在访问数据库两次。我会这样做:

    public function get_permissions($role_id)
    {
        $role = Role::findOrFail($role_id);
        $this->permissions = $role->permissions;
        $this->emitSelf('refreash_permissions');
    }
    

    您在更新值之前发出 refreash_permissions

    关于正在发生的事情:

    首先,您没有向Livewire 提供对造成差异问题的行的引用。 https://laravel-livewire.com/docs/2.x/troubleshooting 我建议为该行分配一个 wire:key 引用,这通常是权限 ID,但在这种情况下,您将替换整个部分,因此您应该使用 $loop-&gt;index() 值,如果 Livewire 有多个页面上的元素,可以在其前面加上一个字符串,例如'permission.' . $loop-&gt;index(),以告知 Livewire 此处引用了哪些元素。

    其次,我可能会重命名类 rolePermissions 上的权限参数,以防止 compact() 方法造成变量污染,因为您传递的是带有数组嵌套的数组。

    【讨论】:

    • 我将 wire:key 添加到权限 tr 中,并带有权限 id 的值,但这无济于事。也应用了 $loop->index & 什么都没有。
    • 我将一个字符串与 $loop->index 一起添加到 wire:key-value 中,它可以工作,我很感激
    • 哦,是的,实际上应该没问题,wire:key 权限 ID 的问题是它不刷新行而只添加它们,所以实际上循环索引应该是使用的项目,因为那是我们正在替换的内容,道歉,我会更新答案,因为我最初误解了这个问题。
    猜你喜欢
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2020-07-12
    相关资源
    最近更新 更多