php - 无法将具有特征的父组件中的选定数据数组传递给嵌套组件
问题描述
应用结构
- 应用程序/Http/Livewire
- 用户控制器 - Livewire/用户管理/用户控制器
- WithBulkActions - Livewire/Traits/DataTable/WithBulkActions
- 资源/视图/livewire
- UserController Blade - livewire/用户管理/用户控制器
描述
我正在创建一个 CRUD 系统,其中包含删除所选数据的批量操作。我已经提取了负责选择多个项目或选择当前数据表(即 UserController)中的所有项目的逻辑,因此我可以在其他数据表组件中将其用作特征,即 WithBulkActions。该特征只负责选择多个项目或从数据表中选择所有项目。删除数据数组的公共函数方法,存在于数据表组件控制器本身即UserController中。现在,要使带有批量操作的多项选择起作用,我必须在数据表组件刀片视图即 UserController Blade 中包含确认模式,它负责触发删除数据数组的方法。当我包含确认模式以删除用户控制器内的选定数据时,它可以完美运行。虽然每一行都有一个复选框建模为wire:model="selected"
在value="{{ $user->id }}"
foreach 循环内。公共变量在 trait WithBulkActionsselected
中初始化public $selected = [];
,然后在组件 UserController 中使用 trait。
rowsQuery
UserController 组件中的属性在使用过滤器的查询中从 User 模型中获取数据,对其进行排序并将其作为属性返回。
public function getRowsQueryProperty()
{
$query = User::query()
->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
return $this->applySorting($query);
}
然后将rowsQuery
克隆到selectedRowsQuery
特征内的属性中,WithBulkActions。
public function getSelectedRowsQueryProperty()
{
return (clone $this->rowsQuery)
->unless($this->selectAll, fn($query) => $query->whereKey($this->selected));
}
如果正在选择一个数据数组并且应该删除所选数据,public function confirmDeleteBulk()
则负责它,它在 UserController 组件中,以下公共函数调用selectedRowsQuery
属性,该属性在 trait 本身中初始化,然后执行delete() 方法并相应地通知。
public function confirmDeleteBulk()
{
$deleteCount = $this->selectedRowsQuery->count();
foreach ($this->selectedRowsQuery->get() as $queryRow) {
$queryRow->roles()->detach();
}
$this->selectedRowsQuery->delete();
$this->showUserBulkDeletionModal = false;
$this->notify('You\'ve deleted '.$deleteCount.' users');
}
我尝试使用公共函数方法制作一个单独的 livewire 组件,以通过显示确认模式来删除选定的数据,但我无法将选定的行数传递给位于 Livewire/UserManagement/LogicalComponent/UserBulkDeletion 的 UserBulkDeletion 嵌套组件。请告诉我在这种情况下最好的用例,以防我想要的。非常感谢您的帮助,因为我从 2 周以来一直在尝试这样做。
语境
- Livewire 版本:2.3.8
- Laravel 版本:8.24.0
- 高山版本:2.8.0
- 浏览器:铬
编辑
- Livewire/用户管理/用户控制器
class UserController extends Component
{
use WithCachedRows, WithSorting, WithBulkActions, WithPerPagePagination;
public User $user;
public $showFilters = false;
public $filters = [
'search' => "",
'email' => null,
'role' => '',
'date-min' => null,
'date-max' => null,
];
protected $listeners = ['sectionRefresh' => '$refresh'];
public function toggleShowFilters()
{
$this->useCachedRows();
$this->showFilters = ! $this->showFilters;
}
public function resetFilters()
{
$this->reset('filters');
}
public function updatedFilters()
{
$this->resetPage();
}
public function getRowsQueryProperty()
{
$query = User::query()
->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
return $this->applySorting($query);
}
public function getRowsProperty()
{
return $this->cache(function () {
return $this->applyPagination($this->rowsQuery);
});
}
public function getRolesProperty()
{
$roles = Role::all();
return $roles;
}
public function render()
{
return view('livewire.backend.management.audience-management.user-controller', ['users' => $this->rows, 'roles' => $this->roles]);
}
}
- Livewire/UserManagement/LogicalComponent/UserBulkDeletion
class UserBulkDeletion extends Component
{
use WithCachedRows, WithBulkActions, WithSorting;
public $showUserBulkDeletionModal = false;
public User $user;
public $filters = [
'search' => "",
'email' => null,
'role' => '',
'date-min' => null,
'date-max' => null,
];
protected $listeners = ['deleteUserBulk'];
public function deleteUserBulk()
{
$this->useCachedRows();
$this->showUserBulkDeletionModal = true;
}
public function confirmDeleteBulk()
{
$deleteCount = $this->selectedRowsQuery->count();
foreach ($this->selectedRowsQuery->get() as $queryRow) {
$queryRow->roles()->detach();
}
$this->selectedRowsQuery->delete();
$this->showUserBulkDeletionModal = false;
$this->notify('You\'ve deleted '.$deleteCount.' users');
$this->emit('sectionRefresh');
}
public function getRowsQueryProperty()
{
$query = User::query()
->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
return $this->applySorting($query);
}
public function render()
{
return view('livewire.backend.management.audience-management.logical-component.user-bulk-deletion');
}
}
- Livewire/Traits/DataTable/WithBulkActions
trait WithBulkActions
{
public $selectPage = false;
public $selectAll = false;
public $selected = [];
public function renderingWithBulkActions()
{
if ($this->selectAll) $this->selectPageRows();
}
public function updatedSelected()
{
$this->selectAll = false;
$this->selectPage = false;
}
public function updatedSelectPage($value)
{
if ($value) return $this->selectPageRows();
$this->selectAll = false;
$this->selected = [];
}
public function selectPageRows()
{
$this->selected = $this->rows->pluck('id')->map(fn($id) => (string) $id);
}
public function selectAll()
{
$this->selectAll = true;
}
public function getSelectedRowsQueryProperty()
{
return (clone $this->rowsQuery)
->unless($this->selectAll, fn($query) => $query->whereKey($this->selected));
}
}
- 视图/livewire/用户管理/逻辑组件/用户批量删除
<div>
<form wire:submit.prevent="confirmDeleteBulk">
<x-modal.confirmation wire:model.defer="showUserBulkDeletionModal">
<x-slot name="title">Delete User</x-slot>
<x-slot name="content">
@json($selected)
Are you sure you want to delete users? This action is irreversible!
</x-slot>
<x-slot name="footer">
<x-button.secondary wire:click="$set('showUserBulkDeletionModal', false)">Cancel</x-button.primary>
<x-button.primary type="submit">Delete</x-button.primary>
</x-slot>
</x-modal.confirmation>
</form>
</div>
解决方案
要将值从一个 Livewire 组件传递到另一个使用事件。
Livewire 组件可以通过全局事件系统相互通信。只要两个 Livewire 组件位于同一页面上,它们就可以使用事件和侦听器进行通信。
在您的 Livewire 组件之一中,您触发了一个事件,例如
$this->event('usersToDelete', [ 1,2,3 ]);
在另一个组件中,您可以侦听此事件
public class MyOtherComponent extends Component
{
protected $listeners = [
'usersToDelete' => 'deleteUsers'
];
public function deleteUsers(array $user)
{
// .. do something
}
}
推荐阅读
- javascript - 如何在 JavaScript 中访问 Spring Bean?
- java - 使用 C++ 编译和运行 java 文件时无法加载主类
- php - 如何比较 now() 和删除查询的 unix 时间戳?
- git - 如何设置 Jenkins 从代理的 git 用户
- c# - 如何将匿名列列表复制到会话
- javascript - 多个 GetElementByID 不起作用,如何循环 Javascript?
- java - 如何从 SSH 获取输出
- spotfire - Spotfire 过滤器适用于数据集的所有可视化
- random - 如果协商 TLS 1.2 或 TLS 1.1,如何以及为什么必须在 TLS 1.3 中覆盖最后 8 个字节,如下所述?
- javascript - 在 JavaScript Promise 中使用 return