why changeAction not call the action or render when i put it on render method

alnux
Member | 139
+
0
-

hi, i have the next presenter and i was test the changeAction presenter method

    // index, create, store, edit, update, destroy
	public function actionIndex(){

	}

	public function renderIndex() {
		$this->template->title = "Index";
		$this['breadCrumb']->editLink('Dashboard', $this->link(':Admin:User:LoginRegister:dashboard'));
		$this['breadCrumb']->addLink($this->translator->translate('Resources'));
		//bdump($this->changeAction('create'));
		$this->changeAction('create');
		//$class = new ReflectionClass($this->getPresenterName(true));
		//bdump($class->getMethods());
	}

	public function actionCreate() {
		bdump($this->getAction());
		//$class = new ReflectionClass($this->getPresenterName(true));
		//bdump($class->getMethods());
	}

	public function renderCreate() {
		$this->template->title = "Create";
		$this['breadCrumb']->editLink('Dashboard', $this->link(':Admin:User:LoginRegister:dashboard'));
		$this['breadCrumb']->addLink($this->translator->translate('Resources'));
		//$class = new ReflectionClass($this->getPresenterName(true));
		//bdump($class->getMethods());
	}

so i want to ask is why when i put the changeAction in this case into renderIndex method i put
$this->changeAction(‘create’);
call for the create template without pass by actionCreate method and renderCreate method

nightfish
Member | 462
+
+1
-

@alnux The answer to your question lies in the way Nette presenter's lifecycle works.

If you look at the code of changeAction(), you can see that it merely assigns action to $action and $view properties.

When you combine it with presenter's lifecycle, you can see, that the latest moment when calling changeAction() could be taken into accout, is the call to Arrays::invoke($this->onRender, $this); on line 214. If you call it in render*(), there is no automated way that would call actionNewAction() and renderNewAction() methods.

So when you call changeAction('create') in actionIndex(), method renderCreate() will get called.
To me, such behavior is often better implemented by redirecting to the correct action to ensure that both actionCreate() and renderCreate() are called. (Well… it would be, if I didn't use single action presenters, where changeAction() does not make sense at all.)

Marek Bartoš
Nette Blogger | 1121
+
0
-

It's not how it was intended to be used and should probably throw exception once an action method gets executed.
To change action later than at startup, you have to use either redirect or forward methods. changeAction() only forces presenter to call different action and render methods and render different view when it's the time in lifecycle to do so.