Ajax查询在添加新帖子时有效,但在更新实体时不起作用

时间:2015-02-09 02:06:24

标签: ajax symfony

我有两个选择框用于国家,第二个用于城市,第二个用于选择第一个选择。

我的代码是文档 http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data

中的提交表单的动态生成示例

添加新帖子时一切正常,但在尝试更新帖子时,显示城市的 Ajax查询不起作用。

这是控制器

// newAction
/**
* @ParamConverter("agence", options={"mapping": {"agence_slug":"slug"}})
*/
public function newAction(Agence $agence, Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $travel = new Travel();
    $form = $this->createForm(new TravelType($agence), $travel);

    if ($request->getMethod() == 'POST')
    {
        //....
    }

    return $this->render('AppBundle:Dashboard/Travel:new.html.twig',
    array(
        'form'   => $form->createView() ,
        'agence' => $agence,
        ));
}

//editAction
/**
* @ParamConverter("agence", options={"mapping": {"agence_slug":"slug"}})
* @ParamConverter("travel", options={"mapping": {"travel_id":"id"}})
*/
public function editAction(Travel $travel, Agence $agence, Request $request)
{
    $em = $this->getDoctrine()->getManager();

    $form = $this->createForm(new TravelEditType($agence), $travel);

    if ($request->getMethod() == 'POST'){
        //....
    }

    return $this->render('AppBundle:Dashboard/Travel:edit.html.twig',
    array(
        'form' => $form->createView() ,
        'travel' => $travel,
        'agence' => $agence,
        ));
}

travelType ,并且效果很好

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;

//........
use Symfony\Component\Form\FormInterface;
use AppBundle\Entity\Country;

class TravelType extends AbstractType
{
 public function buildForm(FormBuilderInterface $builder, array $options)
 {
  //....
  $formModifier = function (FormInterface $form, Country $country = null) {
        $cities = null === $country ? array() : $country->getCities();

        $form->add('destination', 'entity', array(
            'class'       => 'AppBundle:CityWorld',
            'choices'     => $cities,
            'multiple' => false,
            'expanded' => false,
            'property'    => 'name',
            'label' => 'Destination',
            'attr' => array('class' => 'col-xs-10 col-sm-10', 'placeholder' => 'Destination'),
        ));
    };

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function (FormEvent $event) use ($formModifier) {
            // this would be your entity, i.e. SportMeetup
            $data = $event->getData();

            $formModifier($event->getForm(), $data->getCountry());
        }
    );

    $builder->get('country')->addEventListener(
        FormEvents::POST_SUBMIT,
        function (FormEvent $event) use ($formModifier) {
            // It's important here to fetch $event->getForm()->getData(), as
            // $event->getData() will get you the client data (that is, the ID)
            $country = $event->getForm()->getData();

            // since we've added the listener to the child, we'll have to pass on
            // the parent to the callback functions!
            $formModifier($event->getForm()->getParent(), $country);
        }
    );

    $builder->addEventListener(FormEvents::POST_SUBMIT, function ($event) {
        $event->stopPropagation();
    }, 90000000000000); // Always set a higher priority than ValidationListener

}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\Travel'
    ));
}

public function getName()
{
    return null;
}
}

这是 TravelEditType

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
//........
use Symfony\Component\Form\FormInterface;
use AppBundle\Entity\Country;

class TravelEditType extends TravelType
{
 public function buildForm(FormBuilderInterface $builder, array $options)
 {
    parent::buildForm($builder, $options) ;

 }

 public function getName()
 {
    return null;
 }
}

这是表单和javascript代码

<form method="post" action="" class="form-horizontal" role="form" {{ form_enctype(form) }} >
//.............
</form>

<script type="text/javascript">
var $county = $('#country');

$county.change(function () {
    // ... retrieve the corresponding form.
    var $form = $(this).closest('form');

    var data = {};
    data[$county.attr('name')] = $county.val();
    // Submit data via AJAX to the form's action path.
    $.ajax({
        url: $form.attr('action'),
        type: $form.attr('method'),
        data: data,
        success: function (html) {
            // Replace current position field ...
            $('#city').replaceWith(
                    // ... with the returned one from the AJAX response.
                    $(html).find('#city')
            );
            // Position field now displays the appropriate positions.
        }
    });
});

2 个答案:

答案 0 :(得分:0)

在URI中没有参数的情况下尝试:

dashboard_city_ajax:
    path:  /citiies/ajax
    defaults: { _controller: AppBundle:TravelDashboard:ajaxCities }

使用POST发送数据:

$.ajax({
        url: '{{ path('dashboard_city_ajax') }}',
        type: 'POST',
        data: { agence_slug: '{{ agenceSlug }}' },

您可以在控制器中收到它:

$request->request->get('bar', 'default value if bar does not exist');

答案 1 :(得分:0)

问题在于您的路线匹配。有很多方法可以解决问题。尝试在您的ajax路由requirements中包含匹配的路由,或在$ .ajax函数中使用另一个路由,例如

最简单的方法(如果你不想重建你的控制器)只是重建你的路线并把你的ajax路线放在第一位:

dashboard_city_ajax:
    path:  /{ajax}/{agence_slug}/citiies
    defaults: { _controller: AppBundle:TravelDashboard:ajaxCities }
    requirements:
         ajax: ajax

$.ajax({
        url: '{{ path('dashboard_city_ajax', {'agence_slug': agence.slug, 'ajax': 'ajax' }) }}',
        type: 'POST',
        data: data,

但是正确的方式恕我直言是从请求中获取数据。例如

vplanning_ajax:
    path:   /ajax
    defaults: { _controller: VplanningPageBundle:Page:Ajax }


function getData(init) {
    $.post(
        {{ path('vplanning_ajax') }},
        {
          agence_slug: agence.slug,
          yourdata2: 'yourdata2
         } ,
        function ( data ) {
            handleData(data);
        }
    );
}

在您的控制器中,您只需执行

$agence_slug = $this->request->request->get('agence_slug');
$yourdata2 = $this->request->request->get('yourdata2);

...