Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素

Posted

技术标签:

【中文标题】Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素【英文标题】:Twitter Bootstrap typeahead: get context / calling element with `this` 【发布时间】:2012-09-06 23:22:17 【问题描述】:

我正在使用 Twitter Bootstrap 2.1.1 和 jQuery 1.8.1 的 Typeahead 组件

我正在尝试从 typeahead 的 updater 函数中访问文本框元素。这是我当前的代码,效果很好:

$('#client-search').typeahead(
    source: function (query, process) 
        $.get(url,  query: query , function (data) 
            labels = [];
            mapped = ;
            $.each(data, function(i,item) 
                mapped[item.label] = item.value;
                labels.push(item.label);
            );
            process(labels);
        );
    
    ,updater: function (item) 
        $('#client-id').val(mapped[item]);
        return item;
    
    ,items: 10
    ,minLength: 2
);

我在同一页面上有许多预先输入的搜索框。每个搜索框都有一个 id #xxx-search 和一个对应的隐藏输入,id 为 #xxx-id。我想通过执行以下操作对所有内容重复使用相同的代码:

$('#client-search, #endClient-search, #other-search').typeahead(

    ...

    ,updater: function (item) 
        var target = $(this).attr('id').split('-')[0] + '-id';
        $('#'+target).val(mapped[item]);
        return item;
    

    ...

我认为this 会引用正在使用的文本框元素,但显然不是,因为我在 firebug 中遇到了未定义的错误:

$(this).attr("id") is undefined

当我使用this 而不是$(this) 时,我得到:

this.attr is not a function

谁能帮助完成这项工作?


更新:答案,还有更多!

感谢 benedict_w 在下面的回答,这不仅现在可以完美运行,而且在可重用性方面我也做得更好。

这是我的<input>s 的样子:

<input type="text" autocomplete="off"
    id="client-search"
    data-typeahead-url="/path/to/json"
    data-typeahead-target="client-id">
<input type="hidden" id="client-id" name="client-id">

注意搜索框如何引用隐藏的 ID。这是新的js:

$(':input[data-typeahead-url]').each(function()
    var $this = $(this);
    $this.typeahead(
        source: function (query, process) 
            $.get($this.attr('data-typeahead-url'),  query: query , function (data) 
                labels = [];
                mapped = ;
                $.each(data, function(i,item) 
                    mapped[item.label] = item.value;
                    labels.push(item.label);
                );
                process(labels);
            );
        
        ,updater: function (item) 
            $('#'+$this.attr('data-typeahead-target')).val(mapped[item]);
            return item;
        
        ,items: 10
        ,minLength: 2
    );
);

【问题讨论】:

使用此解决方案时,我在下拉菜单中显示“未定义”选项。 @Xeoncross:自发布此问题以来,bootstrap 和 jQuery 都已更新多次。它可能不再与您使用的版本相关。 【参考方案1】:

您在另一个函数中,因此您需要保存对外部闭包中元素的引用,然后可以将其传递给内部闭包的事件处理程序。您可以使用 $.each() 调用来循环选择器,每次都保存对元素 (this) 的引用 - 例如

$('#client-search, #endClient-search, #other-search').each(function() 
    var $this = $(this);
    $this.typeahead(
        ...

        ,updater: function (item) 
            var target = $this.attr('id').split('-')[0] + '-id';
            $('#'+target).val(mapped[item]);
            return item;
        
        ...
     );

【讨论】:

你会在这里找到更多关于 javascript 闭包的讨论:***.com/questions/111102/… 我在这个问题上苦苦挣扎了 2 个小时。你拯救了我的一天!【参考方案2】:

接受的答案是一个很好的答案,但只是想分享一个实际上不需要外部封闭的替代方案。我正在使用 bootstrap v2.3.1,您可以从 this.$element 获得输入。

例如:

$(':input[data-typeahead-url]').typeahead(
    source: function (query, process) 
        $.get(this.$element.attr('data-typeahead-url'),  query: query , function (data) 
            labels = [];
            mapped = ;
            $.each(data, function(i,item) 
                mapped[item.label] = item.value;
                labels.push(item.label);
            );
            process(labels);
        );
    
    ,updater: function (item) 
        $('#'+this.$element.attr('data-typeahead-target')).val(mapped[item]);
        return item;
    
    ,items: 10
    ,minLength: 2
);

【讨论】:

以上是关于Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素的主要内容,如果未能解决你的问题,请参考以下文章

如何创建可打印的 Twitter-Bootstrap 页面

视频分享Twitter前端CSS框架Bootstrap视频教程

Twitter bootstrap 浮动 div 右

为 Twitter 的 Bootstrap 3.x 按钮设计样式

html HTML,CSS,Bootstrap:使用Twitter Bootstrap进行5列布局

如何让 twitter-bootstrap 导航栏子项在小屏幕上折叠/展开?