如何使用Ajax在索纳塔管理形式? [英] How to use Ajax within Sonata Admin forms?

查看:255
本文介绍了如何使用Ajax在索纳塔管理形式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下字段和协会商户的实体: -

I have a Merchant entity with the following fields and associations:-

/**
 * @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;

标签和类别也有一个多对多的映射。 因此,我们有Tag_Category,Merchant_Tag,Merchant_Category映射表。

The Tags and Categories also have a ManyToMany mapping. So we have Tag_Category, Merchant_Tag, Merchant_Category mapping tables.

现在我想在这些领域进行一些Ajax。

Now I want to perform some ajax on these fields.

我想允许用户首先选择主标签。在主标签的基础上,AJAX刷新的类别只有那些属于该标签和一些更多的操作

I want to allow the user to select the Primary Tag first. On the basis of the Primary Tag, ajax refresh the categories to only those which belong to this Tag and some more operations.

我怎样才能做到这一点?

How can I achieve this?

谢谢!

推荐答案

我是能够使这项工作在几个月前。虽然什么a.aitboudad已共享是准确的。有迹象表明,与Symfony的/奏鸣曲第一定时器可能会面临一些疑难杂症的。

I was able to make this work a few months back. While what a.aitboudad has shared is accurate. There are a few gotcha's that first timers with Symfony/Sonata might face.

下面是步骤。

1>扩展索纳塔CRUD的 edit.html.twig / base_edit.html.twig 为简单起见,我将只使用后者。 复制厂商/包/索纳塔/ AdminBundle /资源/视图/ CRUD / base_edit.html.twig 进入views文件夹对应MerchantAdminController - YourBundle /资源/视图/招商/ base_edit.html.twig

1> Extend Sonata CRUD's edit.html.twig / base_edit.html.twig . For simplicity, I'll use only the latter. Copy vendor/bundles/Sonata/AdminBundle/Resources/views/CRUD/base_edit.html.twig into the views folder corresponding to the MerchantAdminController - YourBundle/Resources/views/Merchant/base_edit.html.twig

2>我们需要告诉我们的MerchantAdmin类使用这个模板所以我们覆盖SonataAdmin的 getEditTemplate 的方法是这样的:

2> We need to tell our MerchantAdmin class to use this template. So we override SonataAdmin's getEditTemplate method like this:

public function getEditTemplate()
{
    return 'YourBundle:Merchant:base_edit.html.twig';
}

3> 下一步,我们需要强> $ C $我们 base_edit.html.twig 。标准的Ajax包括以下的:

3> Next we need to code the Ajax functionality in our base_edit.html.twig . Standard Ajax comprises of the following:

3.1> - 创建的控制器中Ajax请求的动作 我们主要是想获得对应于特定类别的标签ID的列表。但最有可能你只是使用索纳塔的CRUD控制器。

3.1> -- Create an Action in the controller for the Ajax request We primarily want to get a list of category IDs corresponding to a particular tag. But most likely you are just using Sonata's CRUD Controller.

定义你的MerchantAdminController延伸CRUDController

Define your MerchantAdminController which extends 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> - 告诉你的管理服务通过定义其在使用这个新创建的控制器,而不是默认CRUDController YourBundle /资源/配置/ services.yml

3.2> -- Tell your Admin service to use this newly created controller instead of the default CRUDController by defining it in 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]

注意第三个参数是控制器的名字。默认情况下它会一直空。

Notice that the 3rd argument is the name of your controller. By default it would have been null.

3.3> - 创建 getCategoryOptionsFromTagAction 在你的控制器命名的动作。你的Ajax调用将是这一行动。

3.3> -- Create an Action named getCategoryOptionsFromTagAction in your controller. Your Ajax call will be to this 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> - 创建于应用程序/配置/ routing.yml文件。记住,如果你使用的是FOSJsRoutingBundle(否则你就必须努力code这是不是一个好主意),露出你的路线。

3.4> -- Create the corresponding route in app/config/routing.yml. Remember to expose your route if you are using the FOSJsRoutingBundle (else you'll have to hardcode which is not a good idea).

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请求,并使用响应

3.5> -- Make the Ajax Request and use the response

{% 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

Gotcha 1: How to get the Unique ID that is appended to all Sonata elements

解决方法:使用管理员变量,这将给你访问到所有管理类的属性,包括uniqId。请参阅如何使用它code。

Solution: Use the admin variable which will give you access to all the Admin Class's properties including uniqId. See code on how to use it.

疑难杂症2:如何让你的JS路由器。

Gotcha 2: How to get the Router in your JS.

解决方法:默认情况下Symfony2的路由不能在JS工作。你需要使用一个名为FOSJSRouting包(如上所述),并暴露途径。这会给你的JS中访问到路由器的对象了。

Solution: By default Symfony2 Routing doesn't work in JS. You need to use a bundle called FOSJSRouting (explained above) and expose the route. This will give you access to the Router object within your JS too.

我已经修改了我的解决方案稍微使这个例子更清晰。如果您发现任何错误,请随时发表评论。

I have modified my solution slightly to make this example clearer. If you notice anything wrong, please feel free to comment.

这篇关于如何使用Ajax在索纳塔管理形式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆