Jquery select 变化

Jquery select on change

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

<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);

            });
        }
    });
});

它的工作,但第一次,第二次更改不会更改 typeahead 的值,

我在这里错过了什么?

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

这里有几个选项:

a) 使用 synchronous/blocking 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);
});

如果没有打印出您的数据,那么您需要先修复这部分。

Its working but for the first time, The second time change doesn't change the values of the typeahead,

我认为那是因为第二次、第三次等,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(即当前选择的 "Species"),并且您会得到正确的值(例如 CatDog).

参见 jQuery#typeahead('destroy')