如何在不更新父级的情况下更新嵌套组件

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,问题得到解决。