FlashMessages v komponentoch

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Durisvk
Člen | 31
+
0
-

Mám takýto control:

<?php
namespace App\Components\Signin;
class SignInControl extends \Nette\Application\UI\Control {
	/** @var \Nette\Database\Context */
	private $database;
	public function __construct(\Nette\Database\Context $connection) {
		$this->database=$connection;
	}
	protected function beforeRender() {
		$this->invalidateControl('signflashes');
	}
	public function render() {
		$this->template->setFile(__DIR__ . '/signin.latte');
		$this->template->render();

	}

	public function createComponentSigninForm() {
		$form = new SigninForm();
		$form['subm']->onClick[] = callback($this,'signinFormSubmit');
		return $form;
	}
	public function signinFormSubmit(\Nette\Forms\Controls\SubmitButton $btn) {
		$values=$btn->form->getValues();
		$model=new \App\Model\SignInModel($this->database);
		if($model->control($values['name'])) {
			$model->signin(array ($values['name'], $values['mail'], $values['pass']));
			$this->flashMessage('Congratulations, you have been signed in!');
			$this->invalidateControl('signflashes');
		} else {
			$this->flashMessage('Name has been used yet!');
			$this->invalidateControl('signflashes');
		}
	}
}

,takéto latte:

{snippet signflashes}
	<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
{/snippet}
{control signinForm}

a takýtko HomePagePresenter:

<?php

namespace App\Presenters;

use Nette,
	App\Model,
	App\Components\Login;

/**
 * Homepage presenter.
 */
class HomepagePresenter extends BasePresenter
{
	private $database;
	private $authenticator;
	function __construct(Nette\Database\Context $connection) {
		$this->database=$connection;
	}
	private $welcome='Welcome to ArcheryArena!';
	public function renderDefault()
	{
		$this->template->welcome = $this->welcome;
	}

	protected function createComponentLogInForm() {
		$this->authenticator= new \App\Model\MyAuthenticator($this->database);
		$this->user->setAuthenticator($this->authenticator);
		return new \App\Components\Login\LoginControl($this->user);
	}

	protected function createComponentSignInForm() {
		return new \App\Components\Signin\SignInControl($this->database);
	}



}

Problém je v o vypisovaní FlashMessagov v SignInControle. Nevypisujú sa mi.

Šaman
Člen | 2666
+
0
-

To ty je nevypisuješ.
Komponenta má vlastní flashmessages stejně jako presenter, tak buď si dej jejich výpis i do komponenty, nebo musíš volat $this->presenter->flashMessage(…);


Aha, sorry, to latte je šablona komponenty? Tak si dumpni $flashes, jestli se správně předaly, podle toho budeš hledat chybu v latte, nebo v předávání.

Editoval Šaman (17. 8. 2014 14:52)

Tomáš Votruba
Moderator | 1114
+
0
-

@Durisvk Ahoj, zkus řešit situace postupně. Nikde v kódu nepřidáváš ajax, přitom voláš invalidateControl pro přepsání šablon. Bez volání ajaxu to nepůjde.

Tato metoda je dostupná pouze v presenterech, takže ji můžeš odstranit:

protected function beforeRender() {
    $this->invalidateControl('signflashes');
}

Vyzkoušej nahradit $this->invalidateControl(...) redirectem $this->redirect('this').
Pokud ti budou flash message fungovat, pokračuj k ajaxu.

Editoval Tomáš Votruba (17. 8. 2014 16:10)

Durisvk
Člen | 31
+
0
-

Šaman:

Cannot read an undeclared property App\Components\Signin\SignInControl::$flashes.

Tomáš:
Mne už to bez ajaxu fachčilo, akurát ten ajax mi narobil problémy.

vvoody
Člen | 910
+
0
-

Tie flash message sa ti do sablóny dostanú až po redirecte (v url pribudne nieco ako fid=xyz). Keď si to nemal zajaxované, tak si tam ten redirect pravdepodobne mal. Tak ho tam daj s5, nemalo by to tomu ajaxu vadit. Len sa miesto jedného ajax requestu vykonajú dva.

Tomáš Votruba
Moderator | 1114
+
0
-

@Durisvk Jak aktivujes ajax?

Flashes jsou v komponente ve $this->template->flashes ci primo v .latte ve $flashes.

Co se presne deje muzes zjistit tak, ze das v Chrome F12, zalozka Network a dat odeslat. Prida se ti ajax request, mas-li jej ma formulari aktivovany. Tam najdes response.

Durisvk
Člen | 31
+
0
-

Ok takže už mi to dumpuje tie flashe(dal som $this->template->flashes) odoslanie formulára funguje krásne, v networku mi píše post request že bol odoslaný, akurát že sa mi nevypisujú tie flashe. Skúšal som tam dať aj redirect ako mi vvoody kázal, ale nepomohlo. momentálne som na tom takto:

class SignInControl extends \Nette\Application\UI\Control {
	/** @var \Nette\Database\Context */
	private $database;
	public function __construct(\Nette\Database\Context $connection) {
		$this->database=$connection;
	}
	protected function beforeRender() {
		$this->invalidateControl('signflashes');
	}
	public function render() {
		$this->template->setFile(__DIR__ . '/signin.latte');
		dump($this->template->flashes);
		$this->template->render();

	}

	public function createComponentSigninForm() {
		$form = new SigninForm();
		$form['subm']->onClick[] = callback($this,'signinFormSubmit');
		return $form;
	}
	public function signinFormSubmit(\Nette\Forms\Controls\SubmitButton $btn) {
		$values=$btn->form->getValues();
		$model=new \App\Model\SignInModel($this->database);
		if($model->control($values['name'])) {
			$model->signin(array ($values['name'], $values['mail'], $values['pass']));
			$this->flashMessage('Congratulations, you have been signed in!');
			$this->invalidateControl('signflashes');
			redirect();
		} else {
			$this->flashMessage('Name has been used yet!');
			$this->invalidateControl('signflashes');
			redirect();
		}
	}
}
Tomáš Votruba
Moderator | 1114
+
0
-

Tomáš Votruba napsal(a):

@Durisvk Jak aktivujes ajax?

Durisvk
Člen | 31
+
0
-

v default.latte
odchytavam odoslanie formu

{* This is the welcome page, you can delete it *}

{block content}
	{snippet flash}
		<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
	{/snippet}
	{snippet sendForm}
		<h1>{$welcome}</h1>
	{/snippet}
	<div id="log_in">
		<h2>Log In!</h2>
			{control logInForm}
			<p class="small">Don't have an account yet? <input type="button" id="sign_link" value="Sign In"></p>
	</div>
	<div id="sign_in">
		<h2>Sign In!</h2>
		{control signInForm}
	</div>

	<script type="text/javascript">
	$(document).ready(function() {
		jQuery.ajaxSetup({
		 cache: false,
		 dataType: 'json',
		 success: function (data) {
		 }
		});
		$("form.ajax").submit(function(e) {
			e.preventDefault();
			$.post(this.action, $(this).serialize(), function(data) {
			alert(data);
			});
		});



		$("#sign_link").click(function () {
			$( '#log_in' ).hide('slide', { direction: 'left' });
			$( '#sign_in' ).show('slide', { direction: 'right' });
		});
	});
	</script>
	<style>
		#log_in {
			position: absolute;
		}
		#sign_in {
			position: absolute;
			display:none;
		}
		.small {
			color:#CCCCFF;
			font-size: 12px;
		}
	</style>
{/block}
Durisvk
Člen | 31
+
0
-

už mi aj v Networku zobrazuje prichádzajúci snippet, len ho neviem nijak raz vykresliť

Tomáš Votruba
Moderator | 1114
+
0
-

Jak jsem odkazoval dříve, použij nette.ajax.js. Ten je s aktuálním nette kompatibilní a kód by ti tam fungoval.

Durisvk
Člen | 31
+
0
-

v Networku mi príde response:

array (1)
0 ⇒ stdClass #c9ad
| message ⇒ „Name has been used yet!“ (23) | type ⇒ „info“ (4)
exception ‚ErrorException‘ with message ‚Possible problem: you are sending a HTTP header while already having some data in output buffer. Try OutputDebugger or start session earlier.‘ in /var/www/users/archeryarena/vendor/nette/http/src/Http/Response.php:316Stack trace:#0 [internal function]: Tracy\Debugger::_errorHandler(1024, ‚Possible proble…‘, ‚/var/www/users/…‘, 316, Array)#1 /var/www/users/archeryarena/vendor/nette/http/src/Http/Response.php(316): trigger_error(‚Possible proble…‘, 1024)#2 /var/www/users/archeryarena/vendor/nette/http/src/Http/Response.php(95): Nette\Http\Response->checkHeaders()#3 /var/www/users/archeryarena/vendor/nette/http/src/Http/Response.php(131): Nette\Http\Response->setHeader(‚Content-Type‘, ‚application/jso…‘)#4 /var/www/users/archeryarena/vendor/nette/application/src/Application/Responses/JsonResponse.php(69): Nette\Http\Response->setContentType(‚application/jso…‘)#5 /var/www/users/archeryarena/vendor/nette/application/src/Application/Application.php(156): Nette\Application\Responses\JsonResponse->send(Object(Nette\Http\Request), Object(Nette\Http\Response))#6 /var/www/users/archeryarena/vendor/nette/application/src/Application/Application.php(88): Nette\Application\Application->processRequest(Object(Nette\Application\Request))#7 /var/www/users/archeryarena/www/index.php(8): Nette\Application\Application->run()#8 {main}Unable to log error. Check if directory is writable and path is absolute. Unable to write to log file ‚/var/www/users/archeryarena/log/exception.log‘. Is directory writable?

iguana007
Člen | 970
+
0
-

Mrkni se do Nette log adresáře a najdi si tam html s touto chybou a otevři si to v prohlížeči, mělo by ti být více jasné, kde ti to spadne.

David Kudera
Člen | 455
+
0
-

Myslím, že podle poslední zprávy ve vyhozené výjimce se do logu nepodívá, nemá tam nejspíše nastavený práva..

Durisvk
Člen | 31
+
0
-

počujte hoši, flashe mi v default.latte vykresľuje aj ajaxovo. problém je akonáhle tie flashe presuniem do komponenty. ešte raz moja aktuálna komponenta:

<?php
namespace App\Components\Signin;
class SignInControl extends \Nette\Application\UI\Control {
	/** @var \Nette\Database\Context */
	private $database;
	public function __construct(\Nette\Database\Context $connection) {
		$this->database=$connection;
	}
	public function render() {
		$this->template->setFile(__DIR__ . '/signin.latte');
		$this->flashMessage('Skúšobný flash message');
		dump($this->template->flashes);
		$this->template->render();
	}
	public function afterRender(){
		if ($this->presenter->isAjax() && $this->hasFlashSession())
			$this->invalidateControl('flashes');
	}
	public function createComponentSigninForm() {
		$form = new SigninForm();
		$form->onSubmit[] = array($this, 'signinFormSubmit');
		return $form;
	}
	public function signinFormSubmit(\Nette\Application\UI\Form $form) {
		$values=$form->getValues();
		$model=new \App\Model\SignInModel($this->database);
		if($model->control($values['name'])) {
			$model->signin(array ($values['name'], $values['mail'], $values['pass']));
			$this->presenter->flashMessage('Congratulations, you have successfully been signed in!');
			$this->updateFlashes();
		} else {
			$this->flashMessage('Name has been used yet!');
			$this->updateFlashes();
		}
	}

	private function updateFlashes() {
		if ($this->presenter->isAjax()) {
			$this->invalidateControl('flashes');
		} else {
			$this->redirect('this');
		}
	}
}

a moje signin.latte

	{snippet flashes}
		<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
	{/snippet}
	{control signinForm}

ten skúšobný flash message v render() mi vykreslí. problém je v signinFormSubmit(), tam mi ich nechce vykresliť.

iguana007
Člen | 970
+
0
-
$this->flashMessage('Name has been used yet!');

změň na:

$this->presenter->flashMessage('Name has been used yet!');

i když, jak se teď dívám, tak ti to doplnění volání presenteru „->presenter“ chybí na více místech, např.:

  • $this->invalidateControl(‚signflashes‘); → $this->presenter->invalidateControl(‚signflashes‘);
  • $this->redirect(‚this‘); → $this->presenter->redirect(‚this‘);

Projdi si to a doplň to.

Editoval iguana007 (18. 8. 2014 15:13)