使用AJAX操作编辑Symfony行为

时间:2014-07-10 08:57:30

标签: php ajax symfony

假设我有一个使用大量AJAX请求的应用程序。

当我的请求是AJAX时,有没有办法编辑Symfony行为并自动调用indexAjaxAction而不是indexAction

我已经知道我可以使用Request::isXmlHttpRequest()方法测试请求是否为Ajax但是我希望它是自动的(而不在每个controllerAction中进行测试)。

服务/捆绑是否已经成功?

示例:

<?php 

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

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 Symfony\Bundle\FrameworkBundle\Controller\Controller;

class FooController extends Controller
{
    public function indexAction($vars) { }
    public function indexAjaxAction($vars) { }

    // Other functions
}

2 个答案:

答案 0 :(得分:2)

一种方法是使用稍微修改过的控制器解析器,而不是常规KttpKernel::handleRaw process中的当前控制器解析器。

请注意,我在这里的想法可能不对,而且未经测试。

控制器解析程序类的标识为controller_resolver.class,您可以使用

在配置中使用自定义标识覆盖它

app/config/config.yml ...

.. config stuff ..

parameters:
    controller_resolver.class: Acme\SomeBundle\Controller\ControllerResolver

然后在您的新ControllerResolver ...

namespace Acme\SomeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver
                    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。

答案 1 :(得分:1)

你可能想要查看Symfony的FOSRestBundle,如果你有1个动作可以返回json数据或渲染html模板,这可能非常有用,具体取决于请求方法