如何在不更新父级的情况下更新嵌套组件
How to update nested components without updating parent
我有一个 table,其中包含多行工作列表模型。在 table 中,可以将批量操作分派到队列中。在我的父组件中,我有一个数组 $bulkIds
并添加一个包含每个分派的批量操作的数组。队列作业完成后,我检查该作业的 ID 是否与保存的 ID 匹配,如果匹配,则检查 emit
一个事件 (bulkActionCompleted
)。这是我在嵌套组件上收到的。我想更新该数组中的行 only,但 without 更新父组件。用户可能正在调度其他队列作业,或分页到其他结果等。我不想干扰用户。
我曾尝试使用 skipRender
,但您不能跳过子项的渲染,一旦子项更新,父项也会更新。
在父级中 html:
<div id="job-listings-table" class="table-body col-12 p-0">
@foreach($jobListings as $index => $jobListing)
@php
$isInBulk = in_array($jobListing->id, array_merge(...$bulkIds));
@endphp
<livewire:employer.job-listings.index.parts.row :jobListing="$jobListing"
:isInBulk="$isInBulk"
:lastJobIds="[]"
:wire:key="$jobListing->id . now()">
</livewire:employer.job-listings.index.parts.row>
@endforeach
</div>
子组件:
class Row extends Component
{
public JobListing $jobListing;
public bool $isInBulk;
public array $lastJobIds = [];
protected $listeners = [
'bulkActionCompleted',
];
public function render()
{
return view('livewire.employer.job-listings.index.parts.row');
}
public function bulkActionCompleted($jobListingIds)
{
$this->lastJobIds = $jobListingIds;
if (in_array($this->jobListing->id, $jobListingIds)) {
$this->isInBulk = false;
}
}
}
TL;DR: 我想更新特定的嵌套组件而不刷新父组件。
事实证明,这是 默认 行为。每当我发出一个被子组件捕获的事件时,当发出事件的函数使用 skipRender
时,父组件不会 "fully" 更新。为静态项添加wire:ignore
,修复父组件中函数运行时引起的问题。
但是我无法解释为什么父级的某些部分仍然得到更新。我想 skipRender
并没有完全跳过整个组件的渲染。
为了更好地解释,调用 skipRender
时,渲染函数甚至不会被调用,但是如果您有可能通过 JS 更改的元素(在我的示例中,至少在一个复选框被选中)将被重置为初始状态。它似乎没有重新渲染 DOM,但它确实重置了。通过向这些特定元素添加 wire:ignore
,问题得到解决。
我有一个 table,其中包含多行工作列表模型。在 table 中,可以将批量操作分派到队列中。在我的父组件中,我有一个数组 $bulkIds
并添加一个包含每个分派的批量操作的数组。队列作业完成后,我检查该作业的 ID 是否与保存的 ID 匹配,如果匹配,则检查 emit
一个事件 (bulkActionCompleted
)。这是我在嵌套组件上收到的。我想更新该数组中的行 only,但 without 更新父组件。用户可能正在调度其他队列作业,或分页到其他结果等。我不想干扰用户。
我曾尝试使用 skipRender
,但您不能跳过子项的渲染,一旦子项更新,父项也会更新。
在父级中 html:
<div id="job-listings-table" class="table-body col-12 p-0">
@foreach($jobListings as $index => $jobListing)
@php
$isInBulk = in_array($jobListing->id, array_merge(...$bulkIds));
@endphp
<livewire:employer.job-listings.index.parts.row :jobListing="$jobListing"
:isInBulk="$isInBulk"
:lastJobIds="[]"
:wire:key="$jobListing->id . now()">
</livewire:employer.job-listings.index.parts.row>
@endforeach
</div>
子组件:
class Row extends Component
{
public JobListing $jobListing;
public bool $isInBulk;
public array $lastJobIds = [];
protected $listeners = [
'bulkActionCompleted',
];
public function render()
{
return view('livewire.employer.job-listings.index.parts.row');
}
public function bulkActionCompleted($jobListingIds)
{
$this->lastJobIds = $jobListingIds;
if (in_array($this->jobListing->id, $jobListingIds)) {
$this->isInBulk = false;
}
}
}
TL;DR: 我想更新特定的嵌套组件而不刷新父组件。
事实证明,这是 默认 行为。每当我发出一个被子组件捕获的事件时,当发出事件的函数使用 skipRender
时,父组件不会 "fully" 更新。为静态项添加wire:ignore
,修复父组件中函数运行时引起的问题。
但是我无法解释为什么父级的某些部分仍然得到更新。我想 skipRender
并没有完全跳过整个组件的渲染。
为了更好地解释,调用 skipRender
时,渲染函数甚至不会被调用,但是如果您有可能通过 JS 更改的元素(在我的示例中,至少在一个复选框被选中)将被重置为初始状态。它似乎没有重新渲染 DOM,但它确实重置了。通过向这些特定元素添加 wire:ignore
,问题得到解决。