소나타 관리 양식 내에서 Ajax를 사용하는 방법은?
다음 필드 및 연관성이 있는 Merchant 엔티티가 있습니다. -
/**
* @ORM\ManyToMany(targetEntity="Category", inversedBy="merchants")
*/
public $categories;
/**
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="merchants")
*/
public $tags;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="merchants")
*/
protected $primaryCategory;
/**
* @ORM\ManyToOne(targetEntity="Tag", inversedBy="merchants")
*/
protected $primaryTag;
태그 및 범주에도 ManyToMany 매핑이 있습니다.그래서 Tag_Category, Merchant_Tag, Merchant_Category 매핑 테이블이 있습니다.
이제 저는 이 분야에서 아약스를 좀 해보고 싶습니다.
사용자가 Primary Tag를 먼저 선택할 수 있도록 하고 싶습니다.기본 태그를 기준으로 ajax는 범주를 이 태그에 속하는 범주 및 일부 추가 작업으로만 새로 고칩니다.
어떻게 하면 이것을 이룰 수 있을까요?
감사합니다!
저는 몇 달 전에 이 일을 해낼 수 있었습니다.a.a.itboudad가 공유한 것은 정확합니다.Symfony/Sonata를 처음 사용하는 사람들이 직면할 수 있는 몇 가지 문제가 있습니다.
여기 단계가 있습니다.
1> 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
방법은 다음과 같습니다.
public function getEditTemplate()
{
return 'YourBundle:Merchant:base_edit.html.twig';
}
3>다음으로 우리는 Ajax 기능을 코드화해야 합니다.base_edit.html.twig
과 같이 됩니다: .됩니다.
3.1> -- Ajax 요청에 대해 컨트롤러에 Action을 만듭니다. 우리는 주로 특정 태그에 해당하는 카테고리 ID의 목록을 가져오길 원합니다.하지만 아마도 여러분은 쏘나타의 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]
세 번째 인수는 컨트롤러의 이름입니다.기본적으로 null이었을 것입니다.
3.3> -- 이름이 지정된 액션 만들기getCategoryOptionsFromTagAction
당신의 조종장치에.Ajax 호출은 이 Action에 대한 것입니다.
// 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
FOSJs 하는 경우 해야 합니다하드 를 작성해야 않습니다 FOSJs 라우팅 번들을 사용하는 경우 경로를 노출해야 합니다(그렇지 않으면 하드코드를 해야 하므로 이는 좋지 않습니다).
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 %}
Gotcha 1 : 모든 소나타 요소에 부가되는 고유 ID를 얻는 방법
해결책:uniqId를 포함한 모든 Admin Class 속성에 액세스할 수 있는 admin 변수를 사용합니다.사용방법에 대한 코드 참조.
Gotcha 2: 라우터를 JS에 가져오는 방법.
해결책:기본적으로 Symfony2 라우팅은 JS에서 작동하지 않습니다.FOSJSRouting이라는 번들(위에서 설명)을 사용하고 경로를 노출해야 합니다.이렇게 하면 JS 내의 Router 개체에도 액세스할 수 있습니다.
이 예시를 좀 더 명확하게 하기 위해 제 솔루션을 약간 수정했습니다.잘못된 점이 발견되면 언제든지 의견을 주세요.
Amit and Lumbendil의 1단계 답변에서 변경해야 합니다.
{% extends base_template %}
안으로
{% extends 'SonataAdminBundle::standard_layout.html.twig' %}
같은 오류가 발생하면
Unable to find template "" in YourBundle:YourObject:base_edit.html.twig at line 34.
아주 상세한 게시물, 단지 재정의 방법을 업데이트하고 관리자 클래스에서 편집 템플릿을 사용하기 위해서입니다.
자, 이렇게 해야 합니다.
// src/AppBundle/Admin/EntityAdmin.php
class EntityAdmin extends Admin
{
public function getTemplate($name)
{
if ( $name == "edit" )
{
// template 'base_edit.html.twig' placed in app/Resources/views/Entity
return 'Entity/base_edit.html.twig' ;
}
return parent::getTemplate($name);
}
}
또는 제공된 방법을 사용하여 서비스 정의에 주입하여 Admin 클래스를 가능한 한 깨끗하게 유지할 수 있습니다.
// app/config/services.yml
app.admin.entity:
class: AppBundle\Admin\EntityAdmin
arguments: [~, AppBundle\Entity\Entity, ~]
tags:
- {name: sonata.admin, manager_type: orm, group: "Group", label: "Label"}
calls:
- [ setTemplate, [edit, Entity/base_edit.html.twig]]
블록 자바스크립트에서 당신은 변경해야 합니다."liszt:updated"
로."chosen:updated"
누군가에게 도움이 되길 바랍니다 ;)
언급URL : https://stackoverflow.com/questions/10118868/how-to-use-ajax-within-sonata-admin-forms
'itsource' 카테고리의 다른 글
API에서 아이폰 IDFA를 검색하는 방법은? (0) | 2023.10.04 |
---|---|
C++에서 파일을 디프하는 방법이 있습니까? (0) | 2023.10.04 |
Angular CLI를 사용하여 패키지를 제거하는 방법? (0) | 2023.10.04 |
PowerShell 언어에서 가장 유용하지만 거의 알려지지 않은 기능은 무엇입니까? (0) | 2023.10.04 |
Wordpress HTML 출력을 개발 목적으로 예쁘게 인쇄 (0) | 2023.10.04 |