细枝呈现VS包括 - 在何时何地使用一个或其他?(Twig render vs include -

2019-09-01 11:30发布

我读过的树枝:渲染VS包括但不是我要找的。 我不知道在哪里和何时应使用渲染,当我应该使用包括,因为这些表述的行为似乎非常相似,我。

什么是这两个词语之间的根本区别是什么?

Answer 1:

有重大差异的{% render %}{% include %}

  • {% render %}标签调用一个动作:当你这样做,你正在执行一个控制器,创建控制器内一个新的上下文并呈现将被添加到您当前视图的视图。

  • {% include %}标签包括当前彼此细枝文件:有没有所谓的动作,所以包含的文件将使用当前上下文(或者你给的参数范围内)来渲染视图。

让我们来看看,在细节。


A {%渲染%}示例

渲染是调用一个动作,如果你是使用路由调用它完全相同的方式,但在内部,没有HTTP事务的标签。 就个人而言,我使用{% render %}当内容包括我的看法需要用ajax被刷新。 这样一来,我能够调用使用标准的路由时,有我的网页内的互动同样的动作。

考虑一个简单的页面与阿贾克斯的形式,帮助您添加的东西,和东西的动态刷新表。

东西实体

<?php

// src/Fuz/HomeBundle/Entity/StuffData.php

namespace Fuz\HomeBundle\Entity;

class StuffData
{

    private $stuff;

    public function getStuff()
    {
        return $this->stuff;
    }

    public function setStuff($stuff)
    {
        $this->stuff = $stuff;
        return $this;
    }

}

东西的形式

<?php

// src/Fuz/HomeBundle/Form/StuffType.php

namespace Fuz\HomeBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class StuffType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('stuff', 'text', array('label' => ''));
    }

    public function getDefaultOptions(array $options)
    {
        return array (
                'data_class' => 'Fuz\HomeBundle\Entity\StuffData',
        );
    }

    public function getName()
    {
        return "Stuff";
    }

}

修改routing.yml文件

# src/Fuz/HomeBundle/Resources/config/routing.yml

fuz_home:
    pattern:  /
    defaults: { _controller: FuzHomeBundle:Default:index }

fuz_add_stuff:
    pattern:  /add_stuff
    defaults: { _controller: FuzHomeBundle:Default:addStuff }

fuz_del_stuff:
    pattern:  /del_stuff
    defaults: { _controller: FuzHomeBundle:Default:delStuff }

fuz_list_stuffs:
    pattern:  /list_stuffs
    defaults: { _controller: FuzHomeBundle:Default:listStuffs }

该控制器

<?php

namespace Fuz\HomeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Fuz\HomeBundle\Entity\StuffData;
use Fuz\HomeBundle\Form\StuffType;

class DefaultController extends Controller
{

    /**
     * Route : fuz_home
     */
    public function indexAction()
    {
        // Initialize some stuffs, stored in the session instead of in a table for simplicity
        if (!$this->get('session')->has('stuffs'))
        {
            $this->get('session')->set('stuffs', array());
        }

        // Create the form used to add a stuff
        $form = $this->createForm(new StuffType(), new StuffData());

        $twigVars = array(
                'formAddStuff' => $form->createView(),
        );

        return $this->render('FuzHomeBundle:Default:index.html.twig', $twigVars);
    }

    /**
     * Route : fuz_add_stuff
     */
    public function addStuffAction()
    {
        $data = new StuffData();
        $form = $this->createForm(new StuffType(), $data);
        $form->bindRequest($this->getRequest());
        if ($form->isValid())
        {
            $stuffs = $this->get('session')->get('stuffs');
            $stuffs[] = $data->getStuff();
            $this->get('session')->set('stuffs', $stuffs);
        }
        return $this->forward("FuzHomeBundle:Default:listStuffs");
    }

    /**
     * Route : fuz_del_stuff
     */
    public function delStuffAction()
    {
        $stuffId = $this->getRequest()->get('stuffId');
        $stuffs = $this->get('session')->get('stuffs');
        if (array_key_exists($stuffId, $stuffs))
        {
            unset($stuffs[$stuffId]);
            $this->get('session')->set('stuffs', array_values($stuffs));
        }
        return $this->forward("FuzHomeBundle:Default:listStuffs");
    }

    /**
     * Route : fuz_list_stuffs
     */
    public function listStuffsAction()
    {
        $stuffs = $this->get('session')->get('stuffs');
        $twigVars = array(
                'stuffs' => $stuffs,
        );
        return $this->render('FuzHomeBundle:Default:listStuffs.html.twig', $twigVars);
    }

该index.html.twig

{# src/Fuz/HomeBundle/Resources/views/Default/index.html.twig #}

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

{# The form that will be posted asynchronously #}
<form id="formStuff">
    {{ form_widget(formAddStuff) }}
    <input type="button" id="add-stuff" value="Add stuff" />
</form>

<br/><br/>

{# The div that will contain the dynamic table #}
<div id="list-stuffs">
    {% render path('fuz_list_stuffs') %}
</div>

{# When a click is made on the add-stuff button, we post the form #}
<script type="text/javascript">
    $('#add-stuff').click(function() {
        $.post('{{ path('fuz_add_stuff') }}',  $('#formStuff').serialize(), function(data) {
            $('#list-stuffs').html(data);
         });
     });
</script>

该listStuffs.html.twig

{#listStuf

fs.html.twig #}

{% if stuffs | length == 0 %}

    No stuff to display !

{% else %}

    <table style="width: 50%">

        {% for stuffId, stuff in stuffs %}
            <tr>
                <td>{{ stuff }}</td>
                <td><a data-stuff-id="{{ stuffId }}" class="delete-stuff">Delete</a></td>
            </tr>
        {% endfor %}

    </table>

<script type="text/javascript">
    $('.delete-stuff').click(function() {
        $.post('{{ path('fuz_del_stuff') }}', {'stuffId': $(this).data('stuff-id')}, function(data) {
            $('#list-stuffs').html(data);
         });
     });
</script>

{% endif %}

这会给你一些丑陋的形式看起来像这样:

问题的关键是:如果你刷新页面,或者如果你添加/删除的东西,同样的控制器将被调用。 无需创建一些复杂的逻辑或重复的代码。


一个{%包括%}示例

[% include %}标签让你包括有关以同样的方式有些一段树枝码作为include在PHP指令工作。 基本上这意味着: {% include %}为您提供了一种方式来在你的应用无处不在重用一些通用的代码。

我们留在我们的东西例如:保持StuffEntity和StuffData但替换以下:

路由:

fuz_home:
    pattern:  /
    defaults: { _controller: FuzHomeBundle:Default:index }

fuz_add_stuff:
    pattern:  /add_stuff
    defaults: { _controller: FuzHomeBundle:Default:addStuff }

fuz_del_stuff:
    pattern:  /del_stuff
    defaults: { _controller: FuzHomeBundle:Default:delStuff }

控制器:

public function indexAction()
{
    // Initialize some stuffs, stored in the session instead of in a table for simplicity
    if (!$this->get('session')->has('stuffs'))
    {
        $this->get('session')->set('stuffs', array());
    }

    // Create the form used to add a stuff
    $form = $this->createForm(new StuffType(), new StuffData());
    $stuffs = $this->get('session')->get('stuffs');

    $twigVars = array(
            'formAddStuff' => $form->createView(),
            'stuffs' => $stuffs,
    );

    return $this->render('FuzHomeBundle:Default:index.html.twig', $twigVars);
}

/**
 * Route : fuz_add_stuff
 */
public function addStuffAction()
{
    $data = new StuffData();
    $form = $this->createForm(new StuffType(), $data);
    $form->bindRequest($this->getRequest());
    if ($form->isValid())
    {
        $stuffs = $this->get('session')->get('stuffs');
        $stuffs[] = $data->getStuff();
        $this->get('session')->set('stuffs', $stuffs);
    }
    return $this->forward("FuzHomeBundle:Default:index");
}

/**
 * Route : fuz_del_stuff
 */
public function delStuffAction()
{
    $stuffId = $this->getRequest()->get('id');
    $stuffs = $this->get('session')->get('stuffs');
    if (array_key_exists($stuffId, $stuffs))
    {
        unset($stuffs[$stuffId]);
        $this->get('session')->set('stuffs', array_values($stuffs));
    }
    return $this->forward("FuzHomeBundle:Default:index");
}

index.html.twig:

{# src/Fuz/HomeBundle/Resources/views/Default/index.html.twig #}

<form action="{{ path('fuz_add_stuff') }}" method="post">
    {{ form_widget(formAddStuff) }}
    <input type="submit" value="Add stuff" />
</form>

<br/><br/>

{# Here we include our "generic" table with the stuff table as parameter #}
{%
    include 'FuzHomeBundle:Default:genericTable.html.twig'
    with {
        'route': 'fuz_del_stuff',
        'data' : stuffs,
    }
%}

genericTable:

{# src/Fuz/HomeBundle/Resources/views/Default/genericTable.html.twig #}

{% if data | length == 0 %}

    No data to display !

{% else %}

    <table style="width: 50%">

        {% for id, elem in data %}
            <tr>
                <td>{{ elem }}</td>
                <td><a href="{{ path(route, {'id': id}) }}">Delete</a></td>
            </tr>
        {% endfor %}

    </table>

{% endif %}

正如你可以在这里看到,只有一个控制器初始化页面(表格和表格)的所有元素,所以这是不可能做异步事务。 但是,你可以在你的应用程序的任何地方包括此genericTable.html.twig文件。


结论

您将使用{% render %}何时插入视图可以使用标准的路由或刷新时插入的观点是完全独立的,从目前的情况下。

您将使用{% include %}当你需要使用一块的树枝代码多次在您的应用程序,但你需要初始化包括视图的情况下需要在相同的动作父树枝文件。



文章来源: Twig render vs include - When and where to use one or the other?