2012-11-01 9 views
15

現在、コントローラのいずれかのアクションに対するAJAXリクエストにより、フルページのHTMLが返されます。Zend Framework 2:Ajaxコールの自動無効化レイアウト

私は、その特定のアクションのHTML(.phtmlコンテンツ)を返すだけです。

次のコードは、不十分手動で特定のアクションのためにレイアウトを無効にすることで問題を解決:

$viewModel = new ViewModel(); 
    $viewModel->setTerminal(true); 
    return $viewModel; 

は、どのように私はAJAX要求が検出されたときに、私のアプリケーションが自動的にレイアウトを無効にすることができますか?これにカスタム戦略を書く必要がありますか?これを行う方法に関するアドバイスは非常に高く評価されます。

また、私のアプリModule.phpで次のコードを試しました.AJAXが正しく検出されていますが、setTerminal()はレイアウトを無効にしていません。

public function onBootstrap(EventInterface $e) 
{ 
    $application = $e->getApplication(); 
    $application->getEventManager()->attach('route', array($this, 'setLayout'), 100); 

    $this->setApplication($application); 

    $this->initPhpSettings($e); 
    $this->initSession($e); 
    $this->initTranslator($e); 
    $this->initAppDi($e); 
} 

public function setLayout(EventInterface $e) 
{ 
    $request = $e->getRequest(); 
    $server = $request->getServer(); 

    if ($request->isXmlHttpRequest()) { 
     $view_model = $e->getViewModel(); 
     $view_model->setTerminal(true); 
    } 
} 

考えられますか?

答えて

7

確かに、別のストラテジーを書くのが最善です。 JsonStrategyは自動的にJson-Formatを返すためにacceptヘッダを自動検出できますが、Ajax-Calls for fullpagesと同様に、自動的に処理しないことが良いです。ページ全体を取得してもよいからです。あなたが言及した上記の解決策は、すぐに行く方法です。

最高速度に向かうときは、追加の行が1つしかありません。常にコントローラ内から完全修飾ViewModelを返すことをお勧めします。同様に:

public function indexAction() 
{ 
    $request = $this->getRequest(); 
    $viewModel = new ViewModel(); 
    $viewModel->setTemplate('module/controller/action'); 
    $viewModel->setTerminal($request->isXmlHttpRequest()); 

    return $viewModel->setVariables(array(
     //list of vars 
    )); 
} 
+0

ありがとう、Sam - 私はまた、アプリのModule.phpで試したアプローチを含めるように私の投稿を更新しました。なぜsetTerminal()がViewModelに影響を与えていないのでしょうか? –

+0

私の推測では、onBootstrapはViewModel()がまだ存在しません。考えられるのは、コントローラにterminal(true)のviewModelを注入し、これを出力に使用することでしょう。 – Sam

0

私はこの質問に答え、それはおそらく似たようだ - Access ViewModel variables on dispatch event

dispatchイベントトリガーにイベントコールバックを取り付けます。このイベントがトリガーされたら、$e->getResult()を呼び出してアクションメソッドの結果を取得できるようにする必要があります。 ViewModelを返すアクションの場合は、setTerminal()の変更を許可する必要があります。

6

私はこの問題は、あなたがレイアウト、ない行動をレンダリングするための責任があるビューモデル$e->getViewModel()setTerminal()を呼んでいるということだと思います。新しいビューモデルを作成してsetTerminal(true)と呼び出し、それを返す必要があります。アクションがAJAXであるか否かを判断する必要はありませんので、私は、専用のAjaxのコントローラを使用します。

use Zend\View\Model\ViewModel; 
use Zend\Mvc\MvcEvent; 
use Zend\Mvc\Controller\AbstractActionController; 

class AjaxController extends AbstractActionController 
{ 
    protected $viewModel; 

    public function onDispatch(MvcEvent $mvcEvent) 
    { 
     $this->viewModel = new ViewModel; // Don't use $mvcEvent->getViewModel()! 
     $this->viewModel->setTemplate('ajax/response'); 
     $this->viewModel->setTerminal(true); // Layout won't be rendered 

     return parent::onDispatch($mvcEvent); 
    } 

    public function someAjaxAction() 
    { 
     $this->viewModel->setVariable('response', 'success'); 

     return $this->viewModel; 
    } 
} 

およびAjax/response.phtmlで単に次

<?= $this->response ?> 
0

aimfeldソリューションは、私の作品あなたのいくつかは、テンプレートの場所の問題を試す場合には、しかし、モジュールを指定しよう:

$this->viewModel->setTemplate('application/ajax/response'); 
4

はここに(私の愚見で)最高のソリューションです。私はそれを理解するのにおよそ2日を費やしました。これまでインターネット上の誰もそれについて投稿していませんでした。

public function onBootstrap(MvcEvent $e) 
{ 
    $eventManager= $e->getApplication()->getEventManager(); 

    // The next two lines are from the Zend Skeleton Application found on git 
    $moduleRouteListener = new ModuleRouteListener(); 
    $moduleRouteListener->attach($eventManager); 

    // Hybrid view for ajax calls (disable layout for xmlHttpRequests) 
    $eventManager->getSharedManager()->attach('Zend\Mvc\Controller\AbstractController', MvcEvent::EVENT_DISPATCH, function(MvcEvent $event){ 

     /** 
     * @var Request $request 
     */ 
     $request = $event->getRequest(); 
     $viewModel = $event->getResult(); 

     if($request->isXmlHttpRequest()) { 
      $viewModel->setTerminal(true); 
     } 

     return $viewModel; 
    }, -95); 

} 

私はまだ満足していません。私はリスナーとしてプラグインを作成し、onBootstrapメソッドの代わりに設定ファイルを使用してプラグインを設定します。しかし、私は= P

+0

結果を覚えておいてくださいコントローラの「ViewModel」は全くではないかもしれません。リクエストが「Zend \ Http \ Request」でない場合もありますので、イベントリスナーを記述する際は注意してください。イベントから何を取得するのかをコントロールに入れてください。リスナーはMVCアプリケーションサイクル全体に影響します。モジュール。 –

+0

コントローラ内でこの特定のビューモデルにアクセスするにはどうすればよいですか? – jkushner

-1
public function myAjaxAction() 
{ 
    .... 
    // View - stuff that you returning usually in a case of non-ajax requests 
    View->setTerminal(true); 
    return View; 
} 
0

最高の素敵なJSONとあなたのために無効にレイアウト&ビューを返しJsonModelを使用することで、次回のためにこれをもらおう。

public function ajaxCallAction() 
    { 
     return new JsonModel(
      [ 
       'success' => true 
      ] 
     ); 
    } 
+0

これは完成したHTMLを送り返したい場合を除いて素晴らしいです。 – David

0

私は以前にこの問題を抱えていましたが、これを解決するためのクイックトリックがあります。すべての

まず、あなたのModule.php設定レイアウトにコントローラレイアウト/空で今module/YourModule/view/layout/empty.phtml

あなたはこのレイアウトで表示するコンテンツをエコーだけする必要があります。レイアウトフォルダにこのよう<?php echo $this->content; ?>

を空のレイアウトを作成しますAjaxリクエストの場合

関連する問題