Istnieją znaczne różnice między {% render %}
i {% include %}
.
{% render %}
tag wywołuje działania: kiedy to robisz, jesteś wykonywania kontrolera, tworząc nowy kontekst wewnątrz tego kontrolera i świadczy, że zostanie dodana do bieżącego widoku.
{% include %}
tag zawiera inny plik w bieżącym gałązka jeden: nie ma działania nazywa, więc dołączony plik użyje aktualny kontekst (lub kontekst dajesz jako parametr) do renderowania widoku.
Zobaczmy to szczegółowo.
odpowiedzi {%}% renderowanie przykład
Render jest tag, który nazywa to działanie bardzo tak samo jakbyś wzywającą go za pomocą trasy, ale wewnętrznie, bez transakcji HTTP. Osobiście używam {% render %}
, gdy zawartość zawarta w moim widoku musi zostać odświeżona przy użyciu ajax. W ten sposób mogę wywołać tę samą akcję za pomocą standardowego routingu, gdy są interakcje na mojej stronie.
Rozważ prostą stronę z formularzem ajaxowym, który pomaga dodawać artykuły i dynamicznie odświeżany spis plików.
Jednostka cd
<?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;
}
}
Formie cd
<?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";
}
}
Plik 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 }
Regulatory
<?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 %}
To daje pewną brzydką postać wygląda tak :
Chodzi o to, że jeśli odświeżysz swoją stronę lub dodasz/usuniesz materiał, ten sam kontroler zostanie wywołany.Nie trzeba tworzyć skomplikowanej logiki ani duplikować kodu.
{% include%} przykładem
Znacznik [% include %}
pozwalają zawierać jakiś kawałek kodu gałązka o taki sam sposób jak dyspozycja include
działa w PHP. To znaczy, w zasadzie: {% include %}
daje drogę do ponownego użycia jakiegoś rodzajowe kawałek kodu w całej aplikacji.
Zatrzymamy się z naszym przykładzie do produkcji wyrobów: zachować StuffEntity i StuffData jednak wymienić następujące:
ułożenia:
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 }
regulatorów:
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 %}
Jak widać tutaj, jest tylko jeden kontroler, który zainicjować całych elementów strony (formy i tabeli), tak że nie jest możliwe do wykonania transakcji asynchronicznych . Możesz jednak dołączyć ten ogólny plik Table.html.twig w dowolnym miejscu aplikacji.
Wnioski
Będziesz korzystać {% render %}
gdy widok wstawić mogą być odświeżane przy użyciu standardowej trasy lub gdy widok wstawić jest całkowicie niezależna od aktualnego kontekstu.
Będziesz używał {% include %}
, gdy będziesz potrzebował użyć kilkukrotnego kodu twig w swojej aplikacji, ale będziesz musiał zainicjować wymagany kontekst widoku widoku w tej samej akcji, co macierzysty plik twig.
Czy oznacza to, że 'return $ this-> render ('MyBundle :: index.html.twig');' w kontrolerze i '{% obejmują MyBundle :: index.html.twig%}' w sposób szablon? – SirDerpington
@SirDerpington I Mean '{% renderowanie%}' lub '{% include%}' zarówno w szablonie gałązka – 0x1gene