mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-24 15:42:09 +08:00
Merge pull request #16340 from filamentphp/fix-state-dehydration
fix: State dehydration with non-unique fields
This commit is contained in:
@@ -170,7 +170,17 @@ trait HasState
|
||||
{
|
||||
if (! ($isDehydrated && $this->isDehydrated())) {
|
||||
if ($this->hasStatePath()) {
|
||||
Arr::forget($state, $this->getStatePath());
|
||||
$rootContainer = $this->getContainer();
|
||||
|
||||
while (! $rootContainer->isRoot()) {
|
||||
$rootContainer = $rootContainer->getParentComponent()->getContainer();
|
||||
}
|
||||
|
||||
$statePath = $this->getStatePath();
|
||||
|
||||
if (! $rootContainer->hasDehydratedComponent($statePath)) {
|
||||
Arr::forget($state, $statePath);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,27 @@ trait HasState
|
||||
return $state;
|
||||
}
|
||||
|
||||
public function hasDehydratedComponent(string $statePath): bool
|
||||
{
|
||||
foreach ($this->getComponents(withHidden: true) as $component) {
|
||||
if (! $component->isDehydrated()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($component->hasStatePath() && ($component->getStatePath() === $statePath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($component->getChildComponentContainers(withHidden: true) as $container) {
|
||||
if ($container->hasDehydratedComponent($statePath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $state
|
||||
* @return array<string, mixed>
|
||||
|
||||
@@ -486,7 +486,7 @@ test('hidden components are excluded from state dehydration except if they are m
|
||||
->fill();
|
||||
|
||||
expect($container)
|
||||
->dehydrateState()->not()->toBe([]);
|
||||
->dehydrateState()->data->not()->toBe([]);
|
||||
|
||||
$container = ComponentContainer::make(Livewire::make())
|
||||
->statePath('data')
|
||||
@@ -505,7 +505,7 @@ test('hidden components are excluded from state dehydration except if they are m
|
||||
->fill();
|
||||
|
||||
expect($container)
|
||||
->dehydrateState()->not()->toBe([]);
|
||||
->dehydrateState()->data->not()->toBe([]);
|
||||
});
|
||||
|
||||
test('hidden components are excluded from state dehydration even if their parent component has a state path', function () {
|
||||
@@ -531,6 +531,74 @@ test('hidden components are excluded from state dehydration even if their parent
|
||||
]);
|
||||
});
|
||||
|
||||
test('components are not excluded from state dehydration if there is another dehydrated field with the same name', function () {
|
||||
$container = ComponentContainer::make(Livewire::make())
|
||||
->statePath('data')
|
||||
->components([
|
||||
(new Component)
|
||||
->statePath($statePath = Str::random())
|
||||
->default(Str::random())
|
||||
->dehydrated(false),
|
||||
(new Component)
|
||||
->statePath($statePath)
|
||||
->default(Str::random()),
|
||||
])
|
||||
->fill();
|
||||
|
||||
expect($container)
|
||||
->dehydrateState()->data->not()->toBe([]);
|
||||
|
||||
$container = ComponentContainer::make(Livewire::make())
|
||||
->statePath('data')
|
||||
->components([
|
||||
(new Component)
|
||||
->statePath($statePath = Str::random())
|
||||
->default(Str::random()),
|
||||
(new Component)
|
||||
->statePath($statePath)
|
||||
->default(Str::random())
|
||||
->dehydrated(false),
|
||||
])
|
||||
->fill();
|
||||
|
||||
expect($container)
|
||||
->dehydrateState()->data->not()->toBe([]);
|
||||
});
|
||||
|
||||
test('hidden components are not excluded from state dehydration if there is another visible field with the same name', function () {
|
||||
$container = ComponentContainer::make(Livewire::make())
|
||||
->statePath('data')
|
||||
->components([
|
||||
(new Component)
|
||||
->statePath($statePath = Str::random())
|
||||
->default(Str::random())
|
||||
->hidden(),
|
||||
(new Component)
|
||||
->statePath($statePath)
|
||||
->default(Str::random()),
|
||||
])
|
||||
->fill();
|
||||
|
||||
expect($container)
|
||||
->dehydrateState()->data->not()->toBe([]);
|
||||
|
||||
$container = ComponentContainer::make(Livewire::make())
|
||||
->statePath('data')
|
||||
->components([
|
||||
(new Component)
|
||||
->statePath($statePath = Str::random())
|
||||
->default(Str::random()),
|
||||
(new Component)
|
||||
->statePath($statePath)
|
||||
->default(Str::random())
|
||||
->hidden(),
|
||||
])
|
||||
->fill();
|
||||
|
||||
expect($container)
|
||||
->dehydrateState()->data->not()->toBe([]);
|
||||
});
|
||||
|
||||
test('disabled components are excluded from state dehydration', function () {
|
||||
$container = ComponentContainer::make(Livewire::make())
|
||||
->statePath('data')
|
||||
@@ -577,7 +645,7 @@ test('disabled components are excluded from state dehydration except if they are
|
||||
->fill();
|
||||
|
||||
expect($container)
|
||||
->dehydrateState()->not()->toBe([]);
|
||||
->dehydrateState()->data->not()->toBe([]);
|
||||
});
|
||||
|
||||
test('disabled components are excluded from state dehydration if their parent component is disabled and not marked as dehydrated', function () {
|
||||
|
||||
Reference in New Issue
Block a user