我想在Ajax中使用Symfony 1.4创建一个“喜欢/不喜欢”按钮。
我有这些表格:
| Song | ------- n --------------------------- n ---------- | sfGuardUser |
|
| LikeSong | `
我已阅读symfony AJAX文档,但它是1.0文档。 1.4很轻。 所以,这是我首先尝试做的。
在/app/frontend/module/likesong/_voting.php
:
<?php
if($song->hasVote())
{
jq_link_to_remote('I do not like', array('complete' => '[??? Update my link]', 'url' => 'likesong/notlike?id_song='.$song->getId()));
}
else
{
jq_link_to_remote('I like', array('complete' => '[??? Update my link]', 'url' => 'likesong/like?id_song='.$song->getId()));
}
echo ' - '.$song->getNbVote();
?>
在/app/frontend/config/routing.yml
:
song_like:
url: /song-like/:id
param: { module: song, action: like }
song_notlike:
url: /song-not-like/:id
param: { module: song, action: notLike }
在/app/frontend/module/likesong/actions.class.php
public function executeLike(sfWebRequest $request)
{
if ($request->isXmlHttpRequest())
{
if(USER HAS NOT YET VOTED)
{
$this->vote = new LikeSong();
$this->vote->setSongId($this->song()->getId());
$this->vote->setSfGuardUserId($this->getUser()->getId());
$this->vote->save();
return $this->renderText('notlike');
else
{
// Display flash
}
}
}
public function executeNotLike(sfWebRequest $request)
{
if ($request->isXmlHttpRequest())
{
if(USER ALREADY VOTED)
{
// Delete form database
return $this->renderText('like');
else
{
// Display flash
}
}
}
当用户点击时,“我喜欢这首歌”应该被“我不喜欢这首歌”所取代。
答案 0 :(得分:3)
首先,您的控制器中不应该有业务逻辑。
您的模板代码也很奇怪 - 我从未使用jq_link_to_remote()
来表示任何ajax,并且快速搜索这个函数,它似乎有很多麻烦。
如果你重新开始构思,你可能会解决很多问题。
用户喜欢或不喜欢的歌曲应写在Song
课程中。我会写这样的东西:
class Song extends BaseSong
{
public function userLike($user_id)
{
return in_array($user_id, $this->getLikers()->getPrimaryKeys()));
}
public function switchLike($user_id)
{
if ($this->userLike($user_id))
{
$this->getLikers()->remove($user_id);
$this->save();
return 0;
}
else
{
$this->getLikers()->add(Doctrine::getTable('User')->find($user_id));
$this->save();
return 1;
}
}
}
您应该始终编写干净的控制器,可以使用或不使用AJAX调用。 isXmlHttpRequest()
功能可以非常强大,但它不能破坏您网站的可访问性。 Javascript必须保持可选,您的链接必须具有标准http调用的功能后备。我会从这样的事情开始:
public function executeIndex(sfWebRequest $request)
{
// Here the code for the whole song's page, which will include your _vote partial
}
public function executeSwitchLike(sfWebRequest $request)
{
$this->song = Doctrine::getTable('Song')->find($request->getParameter('id'));
$this->song->switchLike($this->getUser()->getId());
$this->redirect('song/index?id='.$request->getParameter('id'));
}
然后,使用简单的http链接为“喜欢”或“不喜欢”编写模板。你应该有重新加载整个页面的行为,只需切换“喜欢”状态。
最后,使用简单的jquery.load()
调用重载此链接,该调用仅替换您要替换的HTML元素:
$('#like_block').load('/switchLike?id=<?php echo $song->id ?>');
这将导致整个PHP被执行,这是使用AJAX的好方法,但只重新加载特定的HTML元素。