数か月前にこの作業を行うことができました。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 に対応するビュー フォルダーにコピーします。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 のリストを取得する必要があります。しかし、ほとんどの場合、Sonata の CRUD コントローラーを使用しているだけです。
CRUDController を拡張する MerchantAdminController を定義します
<?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 番目の引数がコントローラーの名前であることに注意してください。デフォルトでは null でした。
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 要素に追加される一意の ID を取得する方法
解決策: uniqId を含むすべての管理クラスのプロパティにアクセスできる管理変数を使用します。使用方法についてはコードを参照してください。
落とし穴 2: JS でルーターを取得する方法。
解決策:デフォルトでは、Symfony2 ルーティングは JS では機能しません。FOSJSRouting (上記で説明) というバンドルを使用して、ルートを公開する必要があります。これにより、JS 内の Router オブジェクトにもアクセスできるようになります。
この例をより明確にするために、ソリューションを少し変更しました。何かおかしなところがありましたら、お気軽にコメントください。