foreach 在 livewire 中表现得很奇怪
foreach in livewire acting weird
我在 Livewire 组件中的每个上方都有两个 table,
我想要做的是当我点击其中一个角色时
第二个 table(权限 table)应该使用提供的角色权限刷新,
第一次和第二次点击它工作得很好,但之后权限 table 开始变长,一些元素开始尿布,这是我的角色控制器:
<?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
在任何点击之后,table 变成 link 这个:
this when the thing become super weird
任何建议,我将不胜感激。
在你的渲染方法中,你有紧凑的数组:
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->index()
值,并且如果 Livewire
在页面上有多个元素,可以在其前面加上一个字符串,例如 'permission.' . $loop->index()
以告知 Livewire 此处引用了哪个元素。
其次,我可能会重命名 class rolePermissions
上的权限参数,以防止使用 compact()
方法造成变量污染,因为您正在传递一个带有数组的数组嵌套。
我在 Livewire 组件中的每个上方都有两个 table, 我想要做的是当我点击其中一个角色时 第二个 table(权限 table)应该使用提供的角色权限刷新, 第一次和第二次点击它工作得很好,但之后权限 table 开始变长,一些元素开始尿布,这是我的角色控制器:
<?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 在任何点击之后,table 变成 link 这个: this when the thing become super weird 任何建议,我将不胜感激。
在你的渲染方法中,你有紧凑的数组:
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->index()
值,并且如果 Livewire
在页面上有多个元素,可以在其前面加上一个字符串,例如 'permission.' . $loop->index()
以告知 Livewire 此处引用了哪个元素。
其次,我可能会重命名 class rolePermissions
上的权限参数,以防止使用 compact()
方法造成变量污染,因为您正在传递一个带有数组的数组嵌套。