1

Symfony 1.4 で Ajax に「好き/嫌い」ボタンを作りたいです。

私はこれらのテーブルを持っています:

| 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
        }
      }
}

ユーザーがクリックすると、「I like this song」が「I don't like this song」に置き換えられます。

4

1 に答える 1

3

まず、コントローラーにビジネスロジックを含めるべきではありません。

あなたのテンプレートコードも奇妙です-私はjq_link_to_remote()ajaxに何も使用したことがなく、この関数についてすばやく検索すると、多くの問題があるようです。受胎に戻ると、おそらく多くの問題が解決されるでしょう。

  1. 曲が好きまたは嫌いなユーザーは、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;
            }
        }
    }
    
  2. AJAXの有無にかかわらず呼び出すことができるクリーンなコントローラーを常に作成する必要があります。このisXmlHttpRequest()機能は非常に強力ですが、Webサイトのアクセシビリティを損なうものであってはなりません。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リンクを使用してテンプレートを作成します。'like'ステータスを切り替えるだけで、ページ全体をリロードする動作が必要です。

最後に、このリンクを単純なjquery.load()呼び出しでオーバーロードします。これは、置き換えようとしているHTML要素のみを置き換えます。

$('#like_block').load('/switchLike?id=<?php echo $song->id ?>');

これにより、PHP全体が実行されます。これはAJAXを操作するための良い方法ですが、特定のHTML要素のみが再ロードされます。

于 2012-12-12T16:39:40.697 に答える