我幾個月前就能完成這項工作。而a.aitboudad所分享的是準確的。第一次與Symfony/Sonata合作的人可能會遇到一些困難。
以下是這些步驟。
1> Extend Sonata CRUD的edit.html.twig
/base_edit.html.twig
。 爲了簡單起見,我只使用後者。 複製vendor/bundles/Sonata/AdminBundle/Resources/views/CRUD/base_edit.html.twig
到views文件夾對應MerchantAdminController - 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請求 我們主要是想獲得對應於特定的標籤類別ID列表的動作。但很可能你只是在使用索納塔的CRUD控制器。
定義您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> - 告訴你的管理服務定義它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]
使用這個新創建的控制器,而不是默認CRUDController注意第三個參數是你的控制器的名字。默認情況下它會是空的。
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:如何獲得追加到所有索納塔元素的唯一ID
解決方案:使用admin變量這將使您可以訪問所有管理類的屬性,包括uniqId。查看如何使用它的代碼。
疑難雜症2:如何讓你的JS路由器。
解決方案:默認情況下,Symfony2的路由不JS工作。您需要使用名爲FOSJSRouting的套件(如上所述)並展示路線。這將使您可以訪問JS內的路由器對象。
我稍微修改了我的解決方案以使此示例更清晰。如果您發現有任何問題,請隨時發表評論。
GRE在答案,很好的細節,不錯的一個!一個問題 - 爲什麼你需要在你的ajax調用中使用FOSJSRouting?將tagId作爲ajax發佈請求的一部分傳遞起來會不會很容易?這樣你可以避免加載額外的軟件包 – lopsided 2012-06-19 15:04:57
謝謝兄弟,FOSJSRouting是訪問路由器對象(Routing.generate(...))來生成路徑的路徑。如果它是一個普通的PHP項目,我們只需要提供文件名 - categories_from_tag.php。但是我們需要在控制器中調用一個動作。 – Amit 2012-06-20 05:11:23
我這樣做的方式是在我的Admin類(TagAdmin)中添加路由:'$ collection-> add('addToGroup',$ this-> getRouterIdParameter()。'/ addToGroup');',使用此路由ajax url like:'url:'{{admin.generateUrl('addToGroup',{'id':object.id})}'',用ajax定義中的extra數據參數:'data:'group = '+ $(this).prevAll('。group-id')。val(),' – lopsided 2012-06-20 08:23:49