1

我正在使用 AngularJS 和 Bootstrap UI 开发一个应用程序。我一直在摸索如何使用 Bootstrap UI 中的 Typeahead 控件。

这是我的 Plunker

我的挑战是我希望用户可以选择一个项目,但不是必须这样做。例如,现在,如果您Test在文本字段中键入并按“Enter”,Test将替换为Alpha. 但是,我真的很想使用Test. 我希望替换文本的唯一时间是有人从下拉列表中选择项目时。我的标记如下所示:

<input type="text" class="form-control" placeholder="Search..."
       ng-model="query"  
       typeahead="result as result.name for result in getResults($viewValue)"
       typeahead-template-url="result.html" />

如何为用户提供选择项目的选项,但仍允许他们输入自己的文本?

4

2 回答 2

1

问题在于,一旦您开始键入EnterTab确认选择当前突出显示的项目和 Typeahead都会自动选择一个项目。

如果您愿意,您可以单击关闭控件以失去焦点或点击Esc退出预先输入,但这些可能难以与您的用户交流。

Bootstrap Ui 中有一个未自动选择/突出显示第一项的请求

一种解决方案是使用到目前为止的查询内容填充第一项,因此 tab 键或输入只会确认当前查询的选择:

JavaScript

angular.module('plunker', ['ui.bootstrap'])
    .filter('concat', function() {
        return function(input, viewValue) {
        if (input && input.length) {
            if (input.indexOf(viewValue) === -1) {
                input.unshift(viewValue);
            }
            return input;
         } else {
            return [];
    }};})

HTML

<input type="text" 
     ng-model="selected" 
     typeahead="state for state in states | filter:$viewValue | limitTo:8 | concat:$viewValue"
     class="form-control">

Plunker 中的演示

于 2014-09-10T13:25:09.563 回答
0

我遇到了同样的情况,没有找到好的答案,所以我自己在ui-bootstrap Here is the relevant answer中实现了它。这可能不是最好的方法,但它确实完成了工作。它使预输入中的第一个结果成为您当前正在输入的内容,因此,如果您使用 tab 键或输入它,它就会被选中——您必须向下箭头或选择另一个选项才能获得它。

是修改后的ui-bootstrap-tpls.js文件

mustMouseDownToMatch在指令中添加了一个属性/属性,例如:

<input type="text" ng-model="selected" typeahead="item for item in typeaheadOptions | filter:$viewValue" typeahead-arrow-down-to-match="true">

和javascript:

var mustArrowDownToMatch = originalScope.$eval(attrs.typeaheadArrowDownToMatch) ? originalScope.$eval(attrs.typeaheadArrowDownToMatch) : false;

我还添加了这个函数,它将当前文本放入预先输入列表的第一项,并使其成为选定项:

var setFirstResultToViewValue = function (inputValue) {
        scope.matches.splice(0, 0, {
        id: 0,
        label: inputValue,
        model: inputValue
    });
}

getMatchesAsync在 typeahead 指令的调用中被调用:

var getMatchesAsync = function(inputValue) {
// do stuff
    $q.when(parserResult.source(originalScope, locals)).then(function(matches) {
        // do stuff
        if (matches.length > 0) {
             // do stuff
        }
        if (mustArrowDownToMatch) {
            setFirstResultToViewValue(inputValue);
            scope.activeIdx = 0;
            setTypeaheadPosition();
        }
        // do stuff
  };
于 2014-09-10T15:12:47.160 回答