Ajax, opozdena aktualizace stranky
- marceln
- Člen | 1
Dobry den,
pisem prvu aplikaciu v nette, je podobna Vzorovej aplikaci Ukolnicek. Namiesto
ukolu mam ale Joby a namito toho aby som ich oznacoval za splnene ich znacim
favorite alebo nie.
V databaze mam tabulku user, tabulku job, a tabulku favorited(fk user_id, fk job_id). User moze oznacit job ako favorite.
mam stranku na ktorej su zobrazene vsetky favorite brigady(=Job) pre daneho uzivatela. ked uzivatel klikne na „odstranit brigadu z oblubenych“ maju sa stat dve veci, zmizne hviezdicka oznacujuca „favorite“ a brigada zmizne zo stranky kedze uz nie je favorite. V reali sa vsak stane len prva vec , zmizne hviezdicka ale brigada nezmizne zo stranky.
Pouzivam ajax script z https://doc.nette.org/cs/quickstart
Video znazornujuce problem: http://www.youtube.com/watch?…
Kod:
<?php
namespace Repo;
use Nette;
class JobListControl extends Nette\Application\UI\Control {
/**
* @var
*/
private $jobs, $enableFavorited, $favorited, $existsJobs, $user, $favoriteRepository;
public function __construct($jobs, $user, FavoriteRepository $favoriteRepository) {
parent::__construct();
$this->user = $user;
$this->jobs = $jobs;
$this->enableFavorited = $user->isInRole('jobseeker');
$this->existsJobs = (count($jobs) > 0);
$this->favoriteRepository = $favoriteRepository;
$this->favorited = array();
}
public function render() {
$this->template->setFile(__DIR__ . '/JobList.latte');
$this->template->jobs = $this->jobs;
foreach ($this->jobs as $job) {
$this->favorited[$job->job_id] =
$this->favoriteRepository->isJobFavorited($job->job_id, $this->user->getId());
}
$this->template->favorited = $this->favorited;
$this->template->enableFavorited = $this->enableFavorited;
$this->template->existsJobs = $this->existsJobs;
$this->template->render();
}
public function handleMarkFavorite($job_id) {
$this->favoriteRepository->addFavorite($job_id, $this->user->getId());
if (!$this->presenter->isAjax()) {
$this->presenter->redirect('this');
}
$this->invalidateControl();
}
public function handleUnmarkFavorite($job_id) {
$this->favoriteRepository->removeFavorite($job_id, $this->user->getId());
if (!$this->presenter->isAjax()) {
$this->presenter->redirect('this');
}
// tu je problem Job sa odstrani z favorites, zmizne hviezdicka pri jobe
// ale list sa prekresli znovu a Job tam stale je , sice uz nie je oznaceny ako favorite
//ale stale tam je
// takze zoznam Jobov je o jeden Ajaxovy krok pozadu za indikaciou hviezdickou
$this->invalidateControl();
}
}
?>
nieco podobne sa riesilo tu:
https://forum.nette.org/…ovy-formular
usudzujem teda ze sa zoznam Jobov z databazy nacita pred tym ako sa ulozi informacia o tom ze job uz nie je favorite.
<?php
/**
* Presenter, který zajišťuje výpis seznamů úkolů.
*
* @property callable $jobFormSubmitted
*/
class JobListPresenter extends BasePresenter {
/** @var Repo\CategoryRepository */
private $categoryRepository;
/** @var Repo\JobRepository */
private $jobRepository;
/** @var Repo\UserRepository */
private $userRepository;
/** @var Repo\ApplicationRepository */
private $applicationRepository;
private $favoriteRepository;
/** @var Nette\Database\Table\ActiveRow */
private $category;
private $jobs;
public function inject(Repo\JobRepository $jobRepository, Repo\CategoryRepository $categoryRepository, Repo\UserRepository $userRepository, Repo\ApplicationRepository $applicationRepository, Repo\FavoriteRepository $favoriteRepository) {
$this->jobRepository = $jobRepository;
$this->categoryRepository = $categoryRepository;
$this->userRepository = $userRepository;
$this->applicationRepository = $applicationRepository;
$this->favoriteRepository = $favoriteRepository;
}
public function createComponentDisplayJobs() {
return new Repo\JobListControl($this->jobs, $this->user, $this->favoriteRepository);
}
public function actionShowCategory($category_id) {
$this->category = $this->categoryRepository->findBy(array('category_id' => $category_id))->fetch();
if ($this->category === FALSE) {
$this->setView('notFound');
}
$this->template->category = $this->category;
$this->jobs = $this->categoryRepository->jobsOf($this->category);
}
public function actionShowAppliedForJobseeker() {
if (!$this->user->isLoggedIn()) {
redirect('Sign:in');
} else if (!$this->user->isInRole('jobseeker')) {
$this->setView('notAuthorized');
}
$applications = $this->applicationRepository->applicationsForJobSeeker($this->user->getId());
$this->jobs = array();
foreach ($applications as $application) {
$this->jobs[] = $this->jobRepository->find($application->job_id);
}
}
// tady je souvisejici metoda
public function actionShowFavoritedForJobseeker() {
if (!$this->user->isLoggedIn()) {
redirect('Sign:in');
} else if (!$this->user->isInRole('jobseeker')) {
$this->setView('notAuthorized');
}
$favorites = $this->favoriteRepository->favoritesForJobSeeker($this->user->getId());
$this->jobs = array();
foreach ($favorites as $favorite) {
$this->jobs[] = $this->jobRepository->find($favorite->job_id);
}
}
}
{block content}
{snippet}
{if $existsJobs}
<table>
<thead>
<tr>
<th>Dátum Zadania</th>
<th>Názov</th>
<th>Zadávateľ</th>
<th>Kategória</th>
<th>Od</th>
<th>Do</th>
{if $enableFavorited}
<th>Obľúbené</th>
{/if}
</tr>
</thead>
<tbody>
{foreach $jobs as $job}
<tr n:class="$iterator->isOdd() ? odd : even">
<td>{$job->created|date:'j. n. Y'}</td>
<td><a href="{plink Job: $job->job_id}">{$job->title}</a></td>
<td>{$job->user->name}</td>
<td>{$job->category->category}</td>
<td>{$job->from_date|date:'j. n. Y'}</td>
<td>{$job->to_date|date:'j. n. Y'}</td>
{if $enableFavorited}
<--! tu je zobrazovanie favorite ikony, toto sa zobrazi spravne hned -->
<td class="action">
<a n:if="!$favorited[$job->job_id]" n:href="markFavorite! $job->job_id" class="icon unstarred ajax">Obľúbené</a>
<a n:if="$favorited[$job->job_id]" n:href="unmarkFavorite! $job->job_id" class="icon starred ajax">Zrušiť</a>
</td>
{/if}
</tr>
{/foreach}
</tbody>
</table>
{else}
<h2>Nie sú brigády</h2>
Pre Vášu voľbu sme nenašli žiadne brigády.
{/if}
{/snippet}
Editoval marceln (9. 1. 2013 21:41)
- besir
- Člen | 170
Ahoj,
1. vec, mimo tvou otazku… proc tu mas toto..:
public function actionShowFavoritedForJobseeker() {
if (!$this->user->isLoggedIn()) {
redirect('Sign:in');
} else if (!$this->user->isInRole('jobseeker')) {
$this->setView('notAuthorized');
}
O t by se Ti mel centralne starat neco jako SecuredPresenter a ACL, myslím, že v tomto případě postačí i statické… https://doc.nette.org/…thentication
a ted k tématu…
Kdysi sem to tu na foru řešil také, ted to nemohu najít… nevadí.
Řešení by mohlo spočívat v tomto..:
public function handleUnmarkFavorite($job_id) {
$this->favoriteRepository->removeFavorite($job_id, $this->user->getId());
if (!$this->presenter->isAjax()) {
$this->presenter->redirect('this');
}
// tady tady...
$this->getPresenter()->invalidateControl();
}
Editoval besir (11. 1. 2013 14:00)