假设我有一个使用大量AJAX请求的应用程序。
是否有一种方法来编辑Symfony行为,并自动调用indexAjaxAction
而不是indexAction
时,我的请求是AJAX ?
我已经知道,我可以测试如果一个请求是Ajax与Request::isXmlHttpRequest()
方法,但我希望它是自动的( I。e无需在每个controllerAction中测试)。
一个服务/bundle已经成功了吗?
例子:
<?php
use SymfonyBundleFrameworkBundleControllerController;
class FooController extends Controller
{
public function indexAction($vars)
{
$request = $this->getRequest();
if($request->isXmlHttpRequest()) {
return $this->indexAjaxAction($vars);
}
// Do Stuff
}
public function indexAjaxAction($vars){ /* Do AJAX stuff */ }
}
是
<?php
use SymfonyBundleFrameworkBundleControllerController;
class FooController extends Controller
{
public function indexAction($vars) { }
public function indexAjaxAction($vars) { }
// Other functions
}
一种方法是使用稍微修改过的控制器解析器,它将取代常规KttpKernel::handleRaw
进程中当前的控制器解析器。
请注意,我的想法可能是错误的,这是未经测试的。
控制器解析器类的id为controller_resolver.class
,您可以使用
在你的app/config/config.yml
…
.. config stuff ..
parameters:
controller_resolver.class: AcmeSomeBundleControllerControllerResolver
然后在你的新ControllerResolver
…
namespace AcmeSomeBundleController;
use SymfonyBundleFrameworkBundleControllerControllerResolver
as BaseControllerResolver;
class ControllerResolver extends BaseControllerResolver
{
/**
* {@inheritdoc
*/
public function getArguments(Request $request, $controller)
{
if (is_array($controller) && $request->isXmlHttpRequest()) {
$action = preg_replace(
'/^(.*?)Action$/',
'$1AjaxAction',
$controller[1]
);
try {
$r = new ReflectionMethod($controller[0], $action);
return $this->doGetArguments(
$request,
$controller,
$r->getParameters()
);
} catch( Exception $e) {
// Do nothing
}
}
return parent::getArguments($request, $controller);
}
}
这个类只是扩展了当前的控制器解析器,如果youractionAjaxAction
存在于控制器中,将尝试使用它,然后如果遇到错误(未找到方法),则返回到常规解析器;
或者你可以直接使用…
if (is_array($controller) && $request->isXmlHttpRequest()) {
$controller[1] = preg_replace(
'/^(?P<action>.*?)Action$/',
'$1AjaxAction',
$controller[1]
);
}
return parent::getArguments($request, $controller);
. .这将只是更新被调用的动作,然后将其发送到常规解析器,没有回退,这意味着每个可以使用XmlHttpRequest
调用的动作都需要相应的AjaxAction。
你可能想看看Symfony的FOSRestBundle,它可以是非常有用的,如果你有一个动作,可以返回json数据或呈现html模板取决于请求方法