【问题标题】:Jquery select on changeJquery选择更改
【发布时间】:2018-05-08 08:28:55
【问题描述】:

我有一个选择框(Specie)和一个 typeAhead 输入字段(Breed),我需要更新选择框的变化,我有以下代码。

<div class="col-lg-4 col-md-4 col-sm-12 col-xs-12 profile-fields-margin-bottom">
    <select class="form-control select_field_style specie-breed" id="species" name="species" required>
        <option disabled selected>Select a Species</option>
        <option value="Dog">Dog</option>
        <option value="Cat">Cat</option>
        <option value="Horse">Horse</option>
    </select>
</div>

<div class="col-lg-4 col-md-4 col-sm-12 col-xs-12 profile-fields-margin-bottom">
    <input id="breed" type="text" class="form-control charsonly" name="breed" placeholder="Breed">
</div>


$(document).on('change', '.specie-breed', function() {
    let specie = this.value;
    $('#breed').typeahead({
        source:  function (query, process) {
            return $.get('/get/breeds/' + specie, { query: query }, function (data) {
                console.log(data);
                return process(data);

            });
        }
    });
});

它的工作,但第一次,第二次更改不会改变预先输入的值,

我在这里错过了什么?

【问题讨论】:

  • 听起来您可能需要使用委托事件处理程序。 process() 函数是否重新创建了 .specie-breed 元素?
  • 您实际上是为每个触发的onchange 事件创建一个新的预输入实例。这会在一段时间后大大降低浏览器的速度。
  • @RoryMcCrossan 是的 process() 函数重新创建 .specie-breed 元素。
  • @Terry 那么最好的方法是什么>
  • 使用委托事件处理程序。有关详细信息,请参阅我标记的副本。

标签: javascript jquery select typeahead.js


【解决方案1】:

它的工作,但第一次,第二次改变没有 更改预先输入的值,

我认为这是因为第二次、第三次等,AJAX URL 不再更改;那是因为 specie 仍然是最初分配给它的值。

我的意思是,假设您从下拉菜单中选择了Cat;因此该菜单的第一个change 事件被触发,并且specie 设置为Cat。但是,当您稍后选择Horse(或Dog)时,source 选项的闭包中的specie 仍为Cat

This Pen可能会帮助你理解它。

因此,一个简单的解决方法是将 specie 引用到 this 而不是 this.value

$(document).on('change', '.specie-breed2', function() {
    let specie = this; // Reference the Element.
    $('#breed').typeahead({
        source:  function (query, process) {
            return $.get('/get/breeds/' + specie.value, { query: query }, function (data) {
                console.log(data);
                return process(data);

            });
        }
    });
});

或者你可以这样做:

$('#breed').typeahead({
    source:  function (query, process) {
        if ( ! $( '#species' ).val() ) {
          return;
        }

        return $.get('/get/breeds/' + $( '#species' ).val(), { query: query }, function (data) {
            console.log(data);
            return process(data);

        });
    }
});

更新

实际的解决方案,或 您在代码中缺少的(我认为)是:在重新初始化 typeahead 之前在 #breed 字段上销毁 typeahead在那个领域

$(document).on('change', '.specie-breed', function() {
    let specie = this.value;

    // Destroy existing instance.
    $('#breed').typeahead( 'destroy' );

    // (Re-)Initialize `typeahead`.
    $('#breed').typeahead({
        source:  function (query, process) {
            return $.get('/get/breeds/' + specie, { query: query }, function (data) {
                console.log(data);
                return process(data);

            });
        }
    });
});

这样,specie 可以分配或引用到this.value(即当前选择的“物种”),并且您会得到正确的值(例如CatDog)。

jQuery#typeahead('destroy')

【讨论】:

  • 你的第一个代码 sn-p 中仍然存在的问题是,每次下拉列表中的值发生变化时,都会调用 typeahead 插件,就好像试图重新初始化它一样(这不起作用)。您在第二次 sn-p 中更正了这一点,您完全消除了不必要的事件处理程序。
  • @gilly3 是的,我确实意识到了这一点。我自己可能会使用第二个 sn-p,或者我不会在同一个 input/字段上重新初始化 typeahead。但是 OP 可能有必要进行重新初始化,因此(在更新的答案中)我建议在 #breed 字段上重新初始化它之前销毁 typeahead 实例。
【解决方案2】:

根据the docstypeaheadsource函数可以接受两个或三个参数。如果你只使用两个,第二个,在你的代码中称为process,必须与结果同步调用。但是,在您的代码中,该回调仅在异步 AJAX 请求之后提供。

你有几个选择:

a) 使用同步/阻塞 GET。这有利于测试,但不应被视为真正的解决方案。

b) 使用source 函数的第三个参数。

请试试这个:

$(document).on('change', '.specie-breed', function() {
    let specie = this.value;
    $('#breed').typeahead({
        source:  function (query, syncResults, asyncResults) {
            $.get('/get/breeds/' + specie, { query: query }, function (data) {
                console.log(data);
                asyncResults(data);
            });
        },
        async: true
    });
});

如果这没有帮助,请确保您的 AJAX 请求成功。 $.get 上的默认处理程序仅适用于 success,但不适用于错误。特别是包含 query 的对象在 GET 请求中看起来很可疑。请在您的页面打开时在控制台中尝试此行:

$.get('/get/breeds/' + specie, { query: query }, function(data) {
    console.log(data);
});

如果那不打印你的数据,那么你需要先修复这部分。

【讨论】:

  • Uncaught TypeError: asyncResults is not a function。 AJAX 调用在那里很好。
  • 但出现上述异常。
  • 我添加了一个明确的async 选项。这有帮助吗?根据文档,该选项应从 source 签名中推断出来。
  • @Gammer 你有没有机会把一个可运行的样本放在一起?带有该 API 和所有内容的完整 URL。不尝试就很难调试。
猜你喜欢
  • 2016-09-28
  • 2011-08-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
相关资源
最近更新 更多