Я смог сделать эту работу несколько месяцев назад. Хотя то, что поделился a.aitboudad, является точным. Есть несколько ошибок, с которыми могут столкнуться новички в Symfony/Sonata.
Вот шаги.
1> Расширение edit.html.twig
/ base_edit.html.twig
Sonata CRUD . Для простоты я буду использовать только последний. Скопируйте vendor/bundles/Sonata/AdminBundle/Resources/views/CRUD/base_edit.html.twig
в папку представлений, соответствующую MerchantAdminController - YourBundle/Resources/views/Merchant/base_edit.html.twig
2> Нам нужно указать нашему классу MerchantAdmin использовать этот шаблон. Поэтому мы переопределяем метод getEditTemplate
SonataAdmin следующим образом:
public function getEditTemplate()
{
return 'YourBundle:Merchant:base_edit.html.twig';
}
3> Далее нам нужно кодировать функциональность Ajax в нашем base_edit.html.twig
. Стандартный Ajax включает в себя следующее:
3.1> -- Создайте действие в контроллере для запроса Ajax. В первую очередь мы хотим получить список идентификаторов категорий, соответствующих определенному тегу. Но, скорее всего, вы просто используете CRUD-контроллер Sonata.
Определите свой MerchantAdminController, который расширяет CRUDController.
<?php
namespace GD\AdminBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use GD\AdminBundle\Entity\Merchant;
class MerchantAdminController extends Controller
{
}
3.2> -- Сообщите службе администратора, что нужно использовать этот вновь созданный контроллер вместо CRUDController по умолчанию, определив его в YourBundle/Resources/config/services.yml
.
gd_admin.merchant:
class: %gd_admin.merchant.class%
tags:
- { name: sonata.admin, manager_type: orm, group: gd_merchant, label: Merchants }
arguments: [null, GD\AdminBundle\Entity\Merchant, GDAdminBundle:MerchantAdmin]
Обратите внимание, что третий аргумент — это имя вашего контроллера. По умолчанию это было бы нулем.
3.3> -- Создайте действие с именем getCategoryOptionsFromTagAction
в своем контроллере. Ваш вызов Ajax будет направлен на это действие.
// route - get_categories_from_tag
public function getCategoryOptionsFromTagAction($tagId)
{
$html = ""; // HTML as response
$tag = $this->getDoctrine()
->getRepository('YourBundle:Tag')
->find($tagId);
$categories = $tag->getCategories();
foreach($categories as $cat){
$html .= '<option value="'.$cat->getId().'" >'.$cat->getName().'</option>';
}
return new Response($html, 200);
}
3.4> -- Создайте соответствующий маршрут в app/config/routing.yml
. Не забудьте открыть свой маршрут, если вы используете FOSJsRoutingBundle (иначе вам придется жестко кодировать, что не очень хорошая идея).
get_categories_from_tag:
pattern: /{_locale}/admin/gd/admin/merchant/get-categories-from-tag/{tagId}
defaults: {_controller: GDAdminBundle:MerchantAdmin:getCategoryOptionsFromTag}
options:
expose: true
3.5> -- сделайте запрос Ajax и используйте ответ
{% block javascripts %}
{{ parent() }}
<script type="text/javascript">
$(document).ready(function(){
var primaryTag = $("#{{ admin.uniqId }}_primaryTag");
primaryTag.change(updateCategories()); // Bind the function to updateCategories
primaryTag.change(); // Manual trigger to update categories in Document load.
function updateCategories(){
return function () {
var tagId = $("#{{ admin.uniqId }}_primaryTag option:selected").val();
var primaryCategory = $("#{{ admin.uniqId }}_primaryCategory");
primaryCategory.empty();
primaryCategory.trigger("liszt:updated");
var locale = '{{ app.request.get('_locale') }}';
var objectId = '{{ admin.id(object) }}'
var url = Routing.generate('get_categories_from_tag', { '_locale': locale, 'tagId': tagId, _sonata_admin: 'gd_admin.merchant', id: objectId });
$.post(url, { tagId: tagId }, function(data){
primaryCategory.empty().append(data);
primaryCategory.trigger("liszt:updated");
},"text");
primaryCategory.val("option:first").attr("selected", true);
};
}
});
</script>
{% endblock %}
Совет 1. Как получить уникальный идентификатор, добавляемый ко всем элементам Sonata
Решение. Используйте переменную администратора, которая предоставит вам доступ ко всем свойствам класса администратора, включая uniqId. См. код о том, как его использовать.
Совет 2. Как получить Router в вашем JS.
Решение. Маршрутизация Symfony2 по умолчанию не работает в JS. Вам нужно использовать пакет под названием FOSJSRouting (описанный выше) и предоставить маршрут. Это также даст вам доступ к объекту Router в вашем JS.
Я немного изменил свое решение, чтобы сделать этот пример более понятным. Если вы заметили что-то не так, пожалуйста, не стесняйтесь комментировать.
person
Amit
schedule
28.05.2012