itsource

소나타 관리 양식 내에서 Ajax를 사용하는 방법은?

mycopycode 2023. 10. 4. 21:52
반응형

소나타 관리 양식 내에서 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.ymlFOSJs 하는 경우 해야 합니다하드 를 작성해야 않습니다 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

반응형