如何解决livewire 中的 foreach 表现得很奇怪
我在 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,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 任何建议我都会很感激。
解决方法
在你的渲染方法中,你有一个紧凑的数组:
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 此处引用了哪个元素。
其次,我可能会重命名类 rolePermissions
上的权限参数,以防止使用 compact()
方法进行变量污染,因为您传递的是带有数组嵌套的数组。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。