如何在Symfony2表单中添加一个自动填充字段用于集合并使用Propel?

前端之家收集整理的这篇文章主要介绍了如何在Symfony2表单中添加一个自动填充字段用于集合并使用Propel?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用Symfony 2.1表单与PropelBundle,我试图重构一个有一个下拉列表的对象(从中选择),而是使用 jquery自动填充字段(使用AJAX)的表单.对于下拉列表,我使用以下代码(在下拉列表中使用的代码)在我的表单类型中:
$builder->add('books','collection',array(
    'type'          => 'model','options'       => array(
        'class'     => 'MyVendor\MyBundle\Model\Book','property'  => 'title',),'allow_add'     => true,'allow_delete'  => true,'by_reference'  => false,'required'      => false,));

为了给出一点上下文,我们假设我们正在创建一个新的“读者”对象,我们希望从可用的“书”对象列表中选择读者喜爱的书籍.使用集合类型,以便可以在新的“读者”表单中选择许多“喜爱的书”.现在,我想更改以上使用自动完成.为此,我尝试实现一个Data Transformer to be able to get a Book object from a simple text field,可以用于自动完成功能,以通过图表ID,如the answer to this Question所示.但是,我无法弄清楚如何使数据变压器与集合类型和Propel类.我创建了一个BookToIdTransformer类,如Symfony Cookbook所示,并在“ReaderType”文件中尝试以下操作:

$transformer = new BookToIdTransformer();
$builder->add(
        $builder->create('books',array(
            'type'          => 'text',))->addModelTransformer($transformer)
);

有了以上,我得到一个“调用undefined方法:getId”异常(显然,Transformer期望一个PropelCollection的书,而不是一个Book对象..).有没有人知道如何去呢?或者让我知道如果有其他方法可以使用Propel实现Symfony中的自动完成,并允许选择多个对象(例如书籍集合)?

解决方法

我最终选择的解决方案与以前的答案略有不同.我最终使用“文本”字段类型,而不是我的“ReaderType”形式的“集合”字段类型,因为我最终使用了允许选择多个对象(例如“喜欢的书”)的 Loopj Tokeninput jQuery plugin与我的主要关联对象(例如“读者”对象).考虑到,我创建了一个“数据变换器”,用于将传递的对象(在文本字段中以逗号分隔的列表)转换为Propel对象集合.代码共享如下,包括一个示例ajax对象控制器.

“ReaderType”表单的关键部分如下所示:

$transformer = new BooksToIdsTransformer();
$builder->add(
    $builder->create('books','text',array(
        'required' => false,))->addModelTransformer($transformer)
);

“数据变压器”文件如下所示:

// src/MyVendor/MyBundle/Form/DataTransformer/BooksToIdsTransformer.PHP
namespace MyVendor\MyBundle\Form\DataTransformer;

use \PropelObjectCollection;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use MyVendor\MyBundle\Model\BookQuery;

class BooksToIdsTransformer implements DataTransformerInterface
{
    public function transform($books)
    {
        if (null === $books) {
            return "";
        }

        if (!$books instanceof PropelObjectCollection) {
            throw new UnexpectedTypeException($books,'\PropelObjectCollection');
        }
        $idsArray = array();
        foreach ($books as $book) {
            $idsArray[] = $book->getId();
        }
        $ids = implode(",",$idsArray);
        return $ids;
    }

    public function reverseTransform($ids)
    {
        $books = new PropelObjectCollection();

        if ('' === $ids || null === $ids) {
            return $books;
        }

        if (!is_string($ids)) {
            throw new UnexpectedTypeException($ids,'string');
        }
        $idsArray = explode(",$ids);
        $idsArray = array_filter ($idsArray,'is_numeric');
        foreach ($idsArray as $id) {
            $books->append(BookQuery::create()->findOneById($id));
        }
        return $books;
    }
}

将“books”的json集合返回到Tokeninput自动完成功能的ajax控制器如下所示:

namespace MyVendor\MyBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use MyVendor\MyBundle\Model\BookQuery;


class ClassAjaxController extends Controller
{
    public function bookAction(Request $request)
    {
        $value = $request->get('q');

        $books = BookQuery::create()->findByName('%'.$value.'%');

        $json = array();
        foreach ($books as $book) {
            $json[] = array(
                'id' => $book->getId(),'name' => $book->getName()
            );
        }

        $response = new Response();
        $response->setContent(json_encode($json));

        return $response;
    }
}

最后,路由器在“routing.yml”文件中:

ajax_book:
    pattern:  /ajax_book
    defaults: { _controller: MySiteBundle:ClassAjax:book }
原文链接:https://www.f2er.com/html/223993.html

猜你在找的HTML相关文章