从Typeahead.js中的symfony控制器获取数据

时间:2014-10-16 13:13:44

标签: javascript json symfony typeahead.js

我想从控制器操作获取数据并在typeahead中解析为json。 每当我尝试获取数据时,我的浏览器的javascript控制台都会出错。

Uncaught TypeError: Cannot use 'in' operator to search for '15014' in [{"id":19,"title":"Getting Started","slug":"getting-started"...

每次我在文本框中更改内容时,数字都会更改。

当我找到Bloodhound直接使用的URL并给它一个查询时,返回带有正确的json格式数据的响应。

searchAction

/**
 * Gets the articles based on a query which is passed from search.js
 *
 * @Route("/search/{query}", name="opifer.manual.help.search", options={"expose"=true})
 * @Method({"POST", "GET"})
 *
 * @param \Symfony\Component\HttpFoundation\Request $request
 *
 * @return \Symfony\Component\HttpFoundation\Response
 */
public function searchAction($query, Request $request)
{
    $searchQuery = $query;
    $artRepo = $this->getDoctrine()->getRepository('OpiferManualBundle:Article');
    $serializer = $this->container->get('jms_serializer');

    // Set search result to be the serialized database entities it the search box is not empty
    if ($searchQuery != "")
    {
        $searchResult = $artRepo->getSearchedArticles($searchQuery);
        $searchResult = $serializer->serialize($searchResult, 'json'); // Serialized the entity
        $response = $searchResult;
        $responseCode = 200;
    }


    $response = json_encode($response); //json encode the array
    return new Response($response, $responseCode, ['Content-Type' => 'application/json']);
}

search.js

/**
 * Created by tomschillemans.
 */
$(document).ready(function() {
    console.log("The Document has been loaded!");

    var remoteUrl = Routing.generate('opifer.manual.help.search', { query: 'WILDCARD' });
    var prefetchUrl = Routing.generate('opifer.manual.help.search_all');
    var articles = new Bloodhound(
    {
        datumTokenizer: function(d)
        {
            return Bloodhound.tokenizers.whitespace(d.val);
        },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote:
        {
            url: remoteUrl,
            wildcard: 'WILDCARD'
        },
        //prefetch: prefetchUrl
    });

    articles.initialize();

    $('#searchfieldId').typeahead(null, {
        name: 'search',
        displayKey: 'title',
        source: articles.ttAdapter(),
        templates:
        {
            empty:
            [
                '<div class="empty-message">',
                    '<p>Unable to find any articles that match the current query</p>',
                '</div>'
            ].join('\n'),
            suggestion: Hogan.compile(
                '<a href="{%url%}">{%title%}</a>',
                {delimiters: '{% %}'}
            )
        },
        engine: Hogan
    });
});

articles.json

{
  "articles":
  [
    {"title": "Getting Started", "slug": "getting-started"},
    {"title": "Markdown Examples", "slug": "markdown-examples"},
    {"title": "Some other article", "slug": "some-other-article"}
  ]
}

2 个答案:

答案 0 :(得分:0)

尝试更改此部分:

    var articles = new Bloodhound(
{
    datumTokenizer: Bloodhound.tokenizers.whitespace('title'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote:
    {
        url: remoteUrl,
        wildcard: 'WILDCARD'
    },
    //prefetch: prefetchUrl
});

使用整个json启用预取,以便在对symfony控制器执行动态请求之前查看autosuggest基础是否有效。

答案 1 :(得分:0)

我这样用:

/**
 * @Route("/enterprise/{query}")
 * @Method("GET")
 * @return JsonResponse
 */
public function enterpriseAction(Request $request)
{
    $service = $this->get('service_enterprise');
    $result = $service->search($request->get('query'));

    return new JsonResponse($result);
}

搜索基本上只是:

/**
 * Search by name
 *
 * @param $query
 * @return array
 */
public function search($query)
{
    $qb = $this->createQueryBuilder('s');
    $qb->select(array('s.slug', 's.name'))
       ->where('s.name LIKE :query')
       ->orderBy('s.name', 'ASC')
       ->setParameter('query', '%'.$query.'%');

    return $qb->getQuery()->getArrayResult();
}

JS部件看起来像这样:

$(document).ready(function(){
   var qEnterprise = new Bloodhound({
       name: 'enterprise',
       remote: '/search/enterprise/%QUERY',
       limit: 10,
       datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.name); },
       queryTokenizer: Bloodhound.tokenizers.whitespace
   });

    qEnterprise.initialize();       

    var typeahead = $('input.typeahead').typeahead(
        {
            hint: true,
            autoselect: true,
            highlight: true,
            minLength: 1
        },
        {
            name: 'enterprise',
            displayKey: 'name',
            source: qEnterprise.ttAdapter(),
            templates: {
                header: '<h4 class="group-name">Konzern</h4>',
                empty: '<div class="tt-suggestion"><p>Kein Treffer</p></div>',
                suggestion: function(data){
                    return '<p><a href="/'+ data.slug +'">'+ data.name +'</a></p>';
                }
            }
        }).on('typeahead:selected', function (object, datum, data) {
            if(data == 'person') {
                document.location.href = '/tag/' + datum.slug;
            }else{
                document.location.href = '/' + datum.slug;
            }
        });
});

您可以在http://www.ichliebediemarke.com

上实时查看