Symfony2 - Twig渲染控制器并返回数组响应

6

注意: 我在这里做的是嵌入控制器 <---查看该链接以获取类似的(官方)示例。

我想从twig模板调用控制器,并使该控制器返回一个数组,然后我可以在模板的其余部分中使用该数组。

我可以通过单独的变量来实现这一点:

Twig

{% set testVar = render(controller('AppBundle:Test:index')) %}

控制器

class TestController extends Controller
{
    public function testAction()
    {
        return new Response('OH HAI');
    }
}

然而,以下代码会抛出异常:("The Response content must be a string or object implementing __toString(), "array" given.")使用相同的Twig文件
public function testAction()
{
    return new Response(array('test' => 1, 'foo' => 'bar'));
}

这会抛出上述的异常。我如何实现我所追求的目标,而不需要创建一个虚拟、无用的额外模板来呈现给控制器?

2
你正在尝试打破MVP模式(试图将逻辑放入视图层)。我的建议是重新考虑你的解决方案。也许如果你说得更多,我可以提供更多帮助。干杯! - Cyprian
1
谢谢您的回复,@Cyprian。我确实感觉这样做是错误的,也许还有其他方法。我的视图分为3个Twig模板,它们都扩展了一个布局模板:headersidebarcontentsidebar需要在每次页面加载时包含动态数据(例如一些实时统计数据)。我需要让侧边栏包含这些数据,无论content模板中包含什么内容。 - Jimbo
我的目标是编写侧边栏,从单独的控制器中检索其自身数据,然后我将来编写的所有内容页面都只是内容页面,我不需要复制任何代码来获取侧边栏的统计信息。 - Jimbo
我会在响应中使用json_encode()函数对数组进行编码,并使用twig扩展在视图中对其进行解码:https://dev59.com/VGUq5IYBdhLWcg3wbv9Z - Bgi
1
好的,我明白了 - 一切都没问题。你应该为侧边栏创建自己的控制器操作,并像你所做的那样将其包含在基本模板中。但是,相反,你的侧边栏操作没有返回任何内容 - 它应该在自己的模板中呈现整个侧边栏视图。因此,调用:{% render(controller('AppBundle:Test:index')) %} 将生成整个侧边栏的HTML代码。我是否正确理解了你的意思?如果是这样,我会在答案中提供更广泛的示例。 - Cyprian
显示剩余3条评论
1个回答

6
实现您想要的标准方法如下:
假设您有常规操作,例如:
class TestController extends Controller
{
    public function testAction()
    {
        return $this->render('AppBundle:Test:index.html.twig');
    }
}

以及模板:

<html>
    <body>
        {% block sidebar %}
            {{ controller('AppBundle:Test:sidebar') }}
        {% endblock %}
        {% block content %}
            Hello world
        {% endblock %}                    
    </body>
</html>

接下来您需要为侧边栏创建一些操作。注意,这样可以避免将任何逻辑放入视图层。

class BaseController extends Controller
{
    public function sidebarAction()
    {
        $status = $this->get('some.status.logic')->retrieveStatus();

        return $this->render('AppBundle:Base:sidebar.html.twig', array(
            'status' => $status,
        ));
    }
}

你的Base/sidebar.html.twig文件:

<div class="sidebar">
   {{ status.showStatusInfo() }}
</div>

就这样。你不会因此破坏MVP模式,因为你的视图层仍然没有任何逻辑(侧边栏的逻辑在中)。


1
我认为我过于担心抽象层次过多,但这似乎是最好的行动方案。干杯! - Jimbo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接