几个月前,我能够完成这项工作。尽管a.aitboudad分享的是准确的。Symfony / Sonata的初学者可能会遇到一些陷阱。
步骤如下。
1 >扩展Sonata CRUD的edit.html.twig
/ base_edit.html.twig
。
为了简单起见,我将仅使用后者。复制
vendor/bundles/Sonata/AdminBundle/Resources/views/CRUD/base_edit.html.twig到与MerchantAdminController对应的views文件夹中-
YourBundle/Resources/views/Merchant/base_edit.html.twig
**2
我们需要告诉我们的MerchantAdmin类使用此模板。**因此,我们重写了SonataAdmin的
getEditTemplate方法,如下所示:
public function getEditTemplate(){ return 'YourBundle:Merchant:base_edit.html.twig';}3 >接下来,我们需要 编写Ajax功能 在我们的
base_edit.html.twig。标准Ajax包括以下内容:
3.1 >
-在控制器中为Ajax请求创建一个Action我们主要希望获得与特定标签相对应的类别ID的列表。但是很可能您只是使用Sonata的CRUD控制器。
定义扩展CRUDController的MerchantAdminController
<?phpnamespace GDAdminBundleController;use SonataAdminBundleControllerCRUDController as Controller;use SymfonyComponentHttpFoundationRequest;use SymfonyComponentHttpFoundationResponse;use GDAdminBundleEntityMerchant;class MerchantAdminController extends Controller{}3.2 >
-通过在中定义它,告诉您的Admin服务使用此新创建的控制器而不是默认的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, GDAdminBundleEntityMerchant, GDAdminBundle:MerchantAdmin]请注意,第三个参数是控制器的名称。默认情况下,它应该为null。
3.3 > -
getCategoryOptionsFromTagAction在控制器中创建一个名为Action的动作。您的Ajax调用将与此操作有关。
// route - get_categories_from_tagpublic 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: true3.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元素的唯一ID
解决方案: 使用admin变量,该变量将使您可以访问所有Admin Class的属性,包括uniqId。请参阅有关如何使用它的代码。
陷阱2: 如何在JS中获取路由器。
解决方案: 默认情况下,Symfony2
Routing在JS中不起作用。您需要使用一个名为FOSJSRouting的包(如上所述)并公开路由。这也将使您能够访问JS中的Router对象。
我对解决方案进行了一些修改,以使此示例更加清晰。如果您发现任何错误,请随时发表评论。



