Ajax, opozdena aktualizace stranky

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

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
+
0
-

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)