17

現在、コントローラー アクションの 1 つに対する AJAX 要求は、フル ページの HTML を返します。

その特定のアクションの 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);
    }
}

考え?

4

8 に答える 8

8

実際、最善の方法は、別の戦略を作成することです。Acceptヘッダーを自動検出してJson-Formatを自動的に返すことができるJsonStrategyがありますが、フルページのAjax-Callsと同様に、フルページを取得したい場合があるため、自動的に処理を行わないのは良いことです。あなたが言及した上記の解決策は、簡単な方法です。

全速力で行く場合、追加のラインは 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
    ));
}
于 2012-11-01T15:32:47.960 に答える
6

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

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 ?>
于 2012-11-30T17:27:30.253 に答える
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

于 2014-02-14T02:16:16.080 に答える
0

私はこの質問に答えましたが、おそらく似ているようです -ディスパッチイベントでViewModel変数にアクセスする

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

于 2012-11-01T16:52:56.430 に答える
0

最高の方法は、Nice json を返す JsonModel を使用し、レイアウトとビューを無効にすることです。

public function ajaxCallAction()
    {
        return new JsonModel(
            [
                'success' => true
            ]
        );
    }
于 2015-02-13T22:33:19.980 に答える
0

私にとってはエイムフェルドのソリューションは機能しますが、テンプレートの場所に関する問題を実験する人がいる場合は、モジュールを指定してみてください。

 $this->viewModel->setTemplate('application/ajax/response');
于 2013-12-19T17:14:16.157 に答える
-2
public function myAjaxAction() 
{
    ....
    // View - stuff that you returning usually in a case of non-ajax requests
    View->setTerminal(true);
    return View;
}
于 2014-06-17T02:38:24.377 に答える