尝试 1
在经历了巨大的挫折之后,我终于得到了这个半成品。
显示所需文本的一种简单方法是为每个项目设置一个toString 方法。
你可能有类似的东西
typeaheadData = [
{id: 1, text: "abc", toString: function() { return "abc"; }},
{id: 2, text: "def", toString: function() { return "def"; }}
]
然后您将在弹出的选项中看到正确的文本,但匹配还不能正常工作(小部件显示的项目与用户在框中输入的文本不匹配)。
为了让这项工作正常进行,我使用了新的 filter 选项,该选项已添加到当前 git 版本的 angular-strap 中。请注意,它甚至不在存储库中预构建的 dist/angular-strap.js 文件中,您需要自己重建此文件才能获得新功能。 (截至提交 ce4bb9de6e53cda77529bec24b76441aeaebcae6)。
如果您的 bs-typeahead 小部件如下所示:
<input bs-typeahead ng-options="item for item in items" filter="myFilter" ng-model="myModel" />
然后,只要用户输入一个键,就会调用过滤器myFilter。它使用两个参数调用,第一个是您传递给typeahead 的整个列表,第二个是输入的文本。然后,您可以遍历列表并返回您想要的项目,可能通过检查文本是否与项目的一个或多个属性匹配。所以你可以像这样定义过滤器:
var myApp = angular.module('myApp', ['mgcrea.ngStrap'])
.filter('myFilter', function() {
return function(items, text) {
var a = [];
angular.forEach(items, function(item) {
// Match an item if the entered text matches its `text` property.
if (item.label.indexOf(text) >= 0) {
a.push(item);
}
});
return a;
};
});
不幸的是,这仍然不太正确;如果您通过单击选择一个项目,则 text 参数将是项目列表中的实际对象,而不是文本。
尝试 2
我仍然觉得这太烦人了,所以我创建了一个 angular-strap (https://github.com/amagee/angular-strap) 的分支,它可以让你这样做:
typeaheadData = [
{id: 1, text: "abc"},
{id: 2, text: "def"}
]
//...
$scope.myFormatter = function(id) {
if (id == null) { return; }
typeaheadData.forEach(function(d) {
if (d.id === id) {
return d.text;
}
});
};
<input bs-typeahead ng-options="item for item in items" ng-model="myModel"
key-field="id" text-field="text" formatter="myFormatter" />
无需对toString 方法或过滤器大惊小怪。 text-field 是用户看到的内容,key-field 是写入模型的内容。
(不!如果您在不通过视图的情况下更新模型仍然不起作用)。
formatter 选项是必需的,因此当您将模型值设置为仅关键字段时,小部件可以找出要显示的正确文本。