Form as component, its handler and possible BC break in 2.3.0?
- Jan Mikeš
- Member | 771
Hey, I am using forms wrapped by components as components and after upgrading from 2.2 to 2.3 i am encountering following error: Component '' is not attached to ‘Nette\Application\UI\Presenter’ in presenter, when trying to set callback for onSuccess event.
Just to mention, i am using Kdyby\Autowired, not using this does not affect this issue
// XyPresenter.php
protected function createComponentXyForm(IControlFactory $factory)
{
$control = $factory->create();
$control["form"]->onSuccess[] = function($form) { // On this line error is occuring
$this->redirect("default");
};
return $control;
}
// Control.php (created by IControlFactory)
protected function createComponentForm(FormFactory $factory)
{
return $factory->create($this->entity);
}
I was able to fix this error adding Nette event to Control and passing form callback to it, instead of directly to the form, like this:
// XyPresenter.php
protected function createComponentXyForm(IControlFactory $factory)
{
$control = $factory->create();
$control->onFormSuccess[] = function($form) {
$this->redirect("default");
};
return $control;
}
// Control.php
public $onFormSuccess = [];
protected function createComponentForm(FormFactory $factory)
{
$form = $factory->create($this->entity);
$form->onSuccess[] = function($form) {
$this->onFormSuccess($form);
};
return $form;
}
I believe that my fix for the problem is much cleaner solution, but is not this unmentioned BC break or why code, which worked on previous version is not working anymore?
Last edited by Lexi (2015-03-13 11:56)
- urug
- Member | 4
I quess the problem is that Nette is proccessing components after the whole
presenter lifecycle is done ( which is really retarded if you ask me). This
includes calling those “createComponent” factories and attaching created
components to presenter (yes the component is attached to presenter after the
presenter is done, you can observe that with a little dumping in
action/render/shutdown/createComponent).
However you can create a component in your presenter's action and attach it to
presenter there, so it's available to presenter for the rest of the presenter
lifecycle.
Last edited by urug (2015-11-27 16:59)
- Jan Mikeš
- Member | 771
@Milo yes it is, notice control's component factory for form. Form's
onSuccess[]
is invoking control event “onFormSuccess”, so the
functionality is same as i would declare
$control["form"]->onSuccess[]
in presenter.
Edit: The difference is when i was trying to access nested component in component i had the exception not attached to presenter… When accessing only top level component everything is fine
Last edited by Lexi (2015-12-02 12:03)