通过 webpacker 实现一个无依赖库

implementing a dependency-less library via webpacker

具有最小依赖性的自动完成功能是一个目标。 js-autocomplete 是一个有趣的候选人。但是,在测试中,这些函数似乎没有触发。

控制器为要自动完成的源数据定义@municipals = Municipal.all.pluck(:name)

页面包括:

  <div id= "search-data" class="form-search search-data" data-municipals="<%= @municipals.to_json %>">
    <%= text_field_tag :q, nil, autocomplete: :off, class: "form-control search-input", placeholder: "Search by municipality..." %>
    <%= submit_tag "Search", class: "btn btn-primary button-home" %>
  </div>

并在底部调用 <%= javascript_pack_tag 'autocomplete.js' %>

autocomplete.js如下

import 'js-autocomplete/auto-complete.css';
import autocomplete from 'js-autocomplete';

const autocompleteSearch = function() {
  const municipals = JSON.parse(document.getElementById('search-data').dataset.municipals)
  const searchInput = document.getElementById('q');

  if (municipals && searchInput) {
    new autocomplete({
      selector: searchInput,
      minChars: 1,
      source: function(term, suggest){
          term = term.toLowerCase();
          const choices = municipals;
          const matches = [];
          for (let i = 0; i < choices.length; i++)
              if (~choices[i].toLowerCase().indexOf(term)) matches.push(choices[i]);
          suggest(matches);
      },
    });
  }
};

export { autocompleteSearch };

并呈现 HTML 使用编译包(此处缩写为 SO 限制)

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId]) {
/******/            return installedModules[moduleId].exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            i: moduleId,
/******/            l: false,
/******/            exports: {}
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.l = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/        if(!__webpack_require__.o(exports, name)) {
/******/            Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/        }
/******/    };
/******/
/******/    // define __esModule on exports
/******/    __webpack_require__.r = function(exports) {
/******/        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/            Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
[...]
//# sourceMappingURL=autocomplete-b628393645bbcc3d2739.js.map

在 text_field_tag

中呈现了一系列城市
<div id= "search-data" class="form-search search-data" data-municipals="[&quot;Ajdovščina&quot;,&quot;Ankaran (Ancarano)&quot;,&quot;Apače&quot;,&quot;Beltinci&quot;,&quot;Benedikt&quot;,&quot;Bistrica ob Sotli&quot;,&quot;Bled&quot;,&quot;Bloke&quot;,&quot;Bohinj&quot;,&quot;Borovnica&quot;   [...] ;]">

<input type="text" name="q" id="q" autocomplete="off" class="form-control search-input" placeholder="Search by municipality..." />

但是输入数据不会触发自动完成。

出现两个问题:

  1. 如何验证该库对页面可用
  2. 似乎对 municipals 数组的引用使得搜索变得不可能。应该如何修复?

这不是一个符合 Rails 约定优于配置的哲学的答案。

但是...目标是最小化依赖性。图书馆也这样做了。

因此只需将脚本(权重的 1/6)和给定页面的用户案例脚本添加到页面底部

<script>
// JavaScript autoComplete v1.0.4
// https://github.com/Pixabay/JavaScript-autoComplete
[...]
</script>
<script>
  var demo1 = new autoComplete({
      selector: '#user_municipal_other',
      minChars: 1,
      source: function(term, suggest){
          term = term.toLowerCase();
          var choices = <%= raw @municipals %>;
          var suggestions = [];
          for (i=0;i<choices.length;i++)
              if (~choices[i].toLowerCase().indexOf(term)) suggestions.push(choices[i]);
          suggest(suggestions);
      }
  });
</script>

在不妨碍他人的情况下激活脚本。

引号问题需要更长的时间才能确定。控制器必须生成 json

@municipals = Municipal.order(name: :asc).all.pluck(:name).to_json

然后 javascript 在结果数组上调用 raw

var choices = <%= raw @municipals %>;

希望这对某些时候有所帮助。