如何让 Algolia Autocomplete 与 Laravel 配合使用?

问题描述 投票:0回答:1

Algolia Autocomplete Github 上,自述文件说:“填充自动完成结果的数据称为源。您可以在源中使用您想要的任何内容...”。然而,我发现除了 Algolia 之外,几乎没有任何关于使用数据源的文档,而且无论有什么文档,都是模糊的。一旦你投入了几个小时,你就会意识到这实际上是一个诱饵和转换。有人向您承诺了一个可以与任何数据源一起使用的自动完成组件,但您发现整个事情的设计目的就是让您只能使用 Algolia。

看,我想做的就是在 Laravel 10 中创建一个 REST 端点并返回一些虚拟数据。例如:

routes/api.php

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;


/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/

Route::get('/test', [TestController::class, 'index']);

app/Http/Controllers/TestController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index(Request $request)
    {
        $results = [
            'results' => [
                ['apple'],
                ['banana'],
                ['strawberry']
            ]
        ];

        return response()->json($results);
    }
}

通过 JS Fetch 向 API 端点发送 GET 请求:

http://localhost/api/test

回应:

注意:我不知道这是否是正确的格式。我找不到这方面的任何文档!

{
   "results":[
      [
         "apple"
      ],
      [
         "banana"
      ],
      [
         "strawberry"
      ]
   ]
}

这是 Algolia 样板:

<div id="autocomplete"></div>
import { autocomplete } from '@algolia/autocomplete-js';

import '@algolia/autocomplete-theme-classic';

autocomplete({
  container: '#autocomplete',
  placeholder: 'Search for products',
  getSources() {
    // What goes here instead of returning an empty array?
    return [];
  },
});
javascript laravel autocomplete algolia
1个回答
0
投票

经过一番尝试和错误,我找到了答案。

这是一个静态示例:

jsfiddle

autocomplete({
  container: '#autocomplete',
  placeholder: 'Search for fruit',
  getSources({ query }) {
    return [
      {
      sourceId: 'suggestions',
      getItems() {
        return [
          {
            name: 'apple'
          },
          {
            name: 'banana'
          },
          {
            name: 'strawberry'
          }
        ].filter(({ name }) =>
          name.toLowerCase().includes(query.toLowerCase())
        );
      },
      templates: {
        item({ item }) {
          return `${item.name}`;
        },
        noResults() {
          return 'No fruit matching.';
        },
      },
      },
    ];
  },
});

REST 端点自动完成功能类似于:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class TestController extends Controller
{
    public function index(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'query'  => 'required'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'status'  => 'error',
                'message' => 'Invalid request.'
            ], 400);
        }

        $query = $request->input('query');

        $fruits = collect([
            ['name' => 'apple'],
            ['name' => 'banana'],
            ['name' => 'strawberry']
        ])->filter(function ($item) use ($query) {
            // Similar to "SELECT * FROM table WHERE column LIKE 'foo%';".
            return str_starts_with($item['name'], $query);
        });

        $results = [];

        foreach ($fruits as $fruit) {
            $results[] = $fruit;
        }

        return response()->json([
            'results' => $results
        ]);
    }
}
autocomplete({
  container: '#autocomplete',
  placeholder: 'Search for fruit',
  getSources({ query }) {
    return [
      {
        sourceId: 'suggestions',
        getItems() {
          return fetch('/api/test?query=' + encodeURIComponent(query))
            .then(response => response.json())
            .then(data => {
              return data.results;
            })
            .catch(error => {
              return [];
            });
        },
        templates: {
          item({ item }) {
            return `${item.name}`;
          },
          noResults() {
            return 'No results matching.';
          },
        },
      },
    ];
  },
});
© www.soinside.com 2019 - 2024. All rights reserved.