路由到 Symfony 2 中的嵌入式模块/捆绑包/控制器

发布于 2024-12-10 21:37:16 字数 1842 浏览 0 评论 0原文

我在研究后完全编辑了这篇文章:

我想在管理部分实现一个侧边栏,它集成在每个页面中,例如 http://example.com/admin/index/

class MyController extends Controller {

    protected $modules = array();

    public function __construct(){
        $this->modules[] = "ModuleController:mainAction";
        $this->modules[] = "OtherModuleController:mainAction";
    }
    
    public function indexAction(Request $request){
        // do stuff here
        return $this->render("MyBundle:My:index.html.twig",$data);
    }
}

在视图中应该发生类似的事情:

{% block modules %}
    {% for module in modules %}
        {% render module %}
    {% endfor %}
{% endblock %}

到目前为止一切顺利,但这些模块可以包含发送帖子的表单请求。我想保持在同一页面上 (http://example.com/admin/index/),因此表单的action属性保持为空。问题是:模块永远不会识别发布请求。因此,一个想法是隐藏相应表单中包含路由名称的字段,将其转换为相应的 uri 并发送子请求(在 MyController 中):

public function indexAction(Request $request){
    if($request->request->has('hidden_module_route')){
        // collect all parameters via $request->request->keys()
        $uri = $router->generate($request->request->get('hidden_module_route'), $parameters);
        // 1: resolve the uri to the according controller and replace the target in the $this->modules array
        // or 2: (after step 1)
        $req = $request->create($uri, 'POST');
        $subresponse = $this->get('kernel')->handle($req,HttpKernelInterface::SUB_REQUEST);
        // inject the response into the modules and handle it in the view
    }
    [...]
}

这对我有用,但我不高兴控制器中的这些职责,感觉应该有一个更好的解决方案(一个想法是注册一个 kernel.controller 侦听器来处理子请求并将路径注入控制器(可能通过标记界面...))。

你怎么认为?

I fully edited this post after doing research:

I'd like to realize a sidebar in the admin section which is integrated in every page, f.e. http://example.com/admin/index/:

class MyController extends Controller {

    protected $modules = array();

    public function __construct(){
        $this->modules[] = "ModuleController:mainAction";
        $this->modules[] = "OtherModuleController:mainAction";
    }
    
    public function indexAction(Request $request){
        // do stuff here
        return $this->render("MyBundle:My:index.html.twig",$data);
    }
}

In the view should happen something like:

{% block modules %}
    {% for module in modules %}
        {% render module %}
    {% endfor %}
{% endblock %}

So far so good, but these modules can contain forms which send post requests. I'd like to stay on the same page (http://example.com/admin/index/), so the action attribute of the form stays empty. The problem is: The post request will never be recognized by the Modules. So one idea was to hide a field in the according form that contains the name of the route, transform it to the according uri and send a sub request (in MyController):

public function indexAction(Request $request){
    if($request->request->has('hidden_module_route')){
        // collect all parameters via $request->request->keys()
        $uri = $router->generate($request->request->get('hidden_module_route'), $parameters);
        // 1: resolve the uri to the according controller and replace the target in the $this->modules array
        // or 2: (after step 1)
        $req = $request->create($uri, 'POST');
        $subresponse = $this->get('kernel')->handle($req,HttpKernelInterface::SUB_REQUEST);
        // inject the response into the modules and handle it in the view
    }
    [...]
}

That would work for me, but I'm not happy to have these responsibilities in the controller and it feels like there should be a better solution (one Idea is to register a kernel.controller listener that handles sub requests and injects the paths to the controller (which perhaps is marked via interface...)).

What do you think?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

Hello爱情风 2024-12-17 21:37:16

您可以尝试将主请求发送到您的模块,以便它们可以将表单与其绑定。

{% block modules %}
    {% for module in modules %}
        {% render module with {'mainRequest': app.request} %}
    {% endfor %}
{% endblock %}

和模块:

public function moduleAction(Request $request, Request $mainRequest)
{
    $form = ...;
    if ($mainRequest->isMethod('POST')) {
        $form->bindRequest($mainRequest);
        if ($form->isValid()) {
            // You can have a beer, that worked
        }
    }
}

You could try to send the main request to your modules, so that they can bind the form with it.

{% block modules %}
    {% for module in modules %}
        {% render module with {'mainRequest': app.request} %}
    {% endfor %}
{% endblock %}

And the module:

public function moduleAction(Request $request, Request $mainRequest)
{
    $form = ...;
    if ($mainRequest->isMethod('POST')) {
        $form->bindRequest($mainRequest);
        if ($form->isValid()) {
            // You can have a beer, that worked
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文