1313
1414use Symfony \Component \EventDispatcher \EventSubscriberInterface ;
1515use Symfony \Component \PropertyAccess \PropertyAccessorInterface ;
16+ use Symfony \UX \LiveComponent \Attribute \AsLiveComponent ;
1617use Symfony \UX \LiveComponent \Util \ModelBindingParser ;
1718use Symfony \UX \TwigComponent \ComponentStack ;
1819use Symfony \UX \TwigComponent \Event \PreMountEvent ;
20+ use Symfony \UX \TwigComponent \MountedComponent ;
1921
2022/**
2123 * Parses the "data-model" key, which triggers extra props to be passed in.
@@ -54,8 +56,9 @@ public function onPreMount(PreMountEvent $event): void
5456 unset($ data ['dataModel ' ]);
5557 $ data ['data-model ' ] = $ dataModel ;
5658
57- // the parent is still listed as the "current" component at this point
58- $ parentMountedComponent = $ this ->componentStack ->getCurrentComponent ();
59+ // find the first parent of the component about to be rendered that is a Live Component
60+ // only those can have properties controlled via the data-model attribute
61+ $ parentMountedComponent = $ this ->getCurrentLiveComponent ($ this ->componentStack );
5962 if (null === $ parentMountedComponent ) {
6063 throw new \LogicException ('You can only pass "data-model" when rendering a component when you \'re rendering inside of a parent component. ' );
6164 }
@@ -76,4 +79,20 @@ public static function getSubscribedEvents(): array
7679 PreMountEvent::class => 'onPreMount ' ,
7780 ];
7881 }
82+
83+ private function getCurrentLiveComponent (ComponentStack $ componentStack ): ?MountedComponent
84+ {
85+ foreach ($ componentStack as $ mountedComponent ) {
86+ if ($ this ->isLiveComponent ($ mountedComponent ->getComponent ()::class)) {
87+ return $ mountedComponent ;
88+ }
89+ }
90+
91+ return null ;
92+ }
93+
94+ private function isLiveComponent (string $ classname ): bool
95+ {
96+ return [] !== (new \ReflectionClass ($ classname ))->getAttributes (AsLiveComponent::class);
97+ }
7998}
0 commit comments