AngularJS BootstrapUI 带有对象和选择功能的 Typeahead

31

我正在尝试使用http://angular-ui.github.io/bootstrap/在Angular中实现类型提示(Typeahead),其中类型提示字段显示完整地址,但是一旦点击,另一个字段将仅填充该地址的邮政编码。我正在尝试使用ng-change或ng-click进行此操作,但没有成功。

http://jsfiddle.net/UxTBB/2/

angular.module('myApp', ['ui.bootstrap'])
    .controller("mainCtrl", function ($scope) {
    $scope.selected = '';
    $scope.states = [{postcode:'B1',address:'Bull ring'},{postcode:'M1',address:'Manchester'}];
    $scope.setPcode = function(site) {
        $scope.selPcode = site.postcode;
        };
});

<div class="container">
    <div ng-controller="mainCtrl" class="row-fluid">
        <form class="row-fluid">
            <div class="container-fluid">
                postcode <input type="text" ng-model="selPcode" />
                typeahead <input type="text"  ng-change="setPcode(site)" ng-model="selected" typeahead="state.address for state in states | filter:$viewValue" />
            </div>
        </form>
    </div>
</div>

有什么想法吗?

6个回答

104

来自http://angular-ui.github.io/bootstrap/的typeahead指令非常灵活,有许多实现所需功能的方法。这里我介绍其中的两种。

首先,typeahead指令的语法与AngularJS的select指令非常相似。这使您完全控制所显示的标签和作为模型值绑定的数据。因此,您可以简单地将地址显示为标签并直接将邮政编码绑定到selPcode

<input type="text" ng-model="selPcode" typeahead="state.postcode as state.address for state in states | filter:$viewValue" typeahead-editable="false" />

这里的关键是as部分在typeahead表达式中:typeahead="state.postcode as state.address for state in states"

另外,请注意我使用了typeahead-editable="false"属性,仅在选择时绑定模型。这里有一个可以工作的jsFiddle: http://jsfiddle.net/jLupa/

如果确实需要使用回调函数的解决方案,则可以使用typeahead-on-select属性:

<input type="text"  typeahead-on-select="setPcode($item)" ng-model="selected" typeahead="state.address for state in states | filter:$viewValue" />

它允许您在选择匹配项时指定回调函数。这里有一个可工作的示例代码:http://jsfiddle.net/t8BV2/

最后需要注意的是,ng-change 在此处不起作用,因为它会对输入中的任何更改做出反应,而您只想捕获选择。 ng-click 也没有太多用处,因为它只对单击输入字段而不是匹配弹出窗口做出反应。除此之外,它也不会对使用键盘进行的选择做出反应。


好的,非常感谢!现在运行良好,除了我正在使用: <input type="text" placeholder="输入以过滤" ng-model="siteAPop" typeahead-editable="false" typeahead="site.postcode as site.name + ',' + site.address + ',' + site.town for site in sites | filter:\$viewValue"> 该字段一开始显示“,,”,而不是我的占位符。有什么想法吗? - stampeder
@stampeder我认为与显示“,,”的字段相关的版本0.4.0中可能存在错误。已在主分支中进行了修正,并将成为下一个发布的一部分。可以随时在https://github.com/angular-ui/bootstrap/issues?state=open中提出问题以确认。 - pkozlowski.opensource
在这个例子中,你会如何选择默认值。当我在控制器中将“setPcode”设置为“M1”时,预期结果是该字段将填充为“曼彻斯特”???? - Meeker
3
+2用于$item。文档中没有看到这一点,很高兴在互联网上找到它。 - Josh C.
感谢您提供的“typeahead-editable”。我已经看到了您的fiddle“http://jsfiddle.net/jLupa/”。我希望模型只能设置为有效的集合。在fiddle中,当我在typeahead框中输入“a”并选择某些内容时,模型可以正常设置。但是等等,如果我现在编辑它呢?我的意思是,我清除“曼彻斯特”并键入“b”,那么它不应该在我选择之前重置模型。现在,它会重置模型!您可以看到文本框为空。这不是应该仅对有效值触发setter的问题吗? - Dhrumil Bhankhar
显示剩余2条评论

4

@pkozlowski-opensource的优秀解决方案有一个缺点:如果你想要展示项的描述而不是项的代码,那么你不能以这种方式从ng-model属性初始化typeahead。

我发现一种通过以下方式配置typeahead解决该问题的方法:

<input type="text" ng-model="selected" typeahead="state as state.address for state in states | filter:$viewValue" />

这将会返回一个状态对象到模型属性,可以通过将值设置为相应的对象来初始化:
    $scope.selected = {postcode:'M1',address:'Manchester'};

这是一个可用的范例:https://jsfiddle.net/0y3ntj4x/3/

我认为angular-bootstrap文档中缺失了这种类型提示的场景。


感谢您的出色回答。所以我尝试开发这个使用自动生成的输入,但它不起作用。嗯,我的错误在哪里? https://jsfiddle.net/0y3ntj4x/10/ - Vahid Alimohamadi
@VahidAlimohamadi 我不明白你的问题。你正在将空对象推入 $scope.selecteds 中。 - Soldeplata Saketos

3

我遇到了类似的问题,

<input type="text" ng-model="select" typeahead="a as a.Value for a in countries | filter:{{ Value:$viewValue }} "class="form-control" typeahead-editable="false" >

{ Code: AL,ParentCode: null,Value: Albania,Id: 1206,Name: countries }

但是使用以下方式调用服务时无法解决:

$scope.countries = []; _services.getcountries(function(result) { $scope.countries = result; });

而通过以下方式解决:

$scope.countries = []; _services.getcountries(function(result) { $.each(result, function(i, o) { $scope.countries.push(o); }); });

希望能对别人有所帮助。


2

我想补充一下由@pkozlowski.opensource提供的答案 - 在Angular的UI-Bootstrap版本0.10.0中,jsfiddle.net/jLupa展示的行为不再有效。请参见此处: jsfiddle.net/jLupa/87/。我所做的唯一更改是更新到版本0.10.0,您可以看到两个输入框都解析为邮政编码。


你找到了在版本0.10.0上使其工作的方法吗?我正在使用版本0.8.0(因为我被困在遗留应用程序上的Bootstrap v2.3.2),并且遇到了同样的问题。这里有内置功能我错过了吗,还是我需要编写自己的代码将标签放回文本框中? - Blair Connolly
1
我在这里“修复”了你的代码。AngularUI 确实很聪明,任何具有选择值的内容都将被显示,即使是在页面刷新或从数据库返回后。所以这就是我一直在寻找的东西。无论如何,如果您需要一个工作示例,请查看这个 Fiddle http://jsfiddle.net/jLupa/421/,我仅更改了选择语句,不选择邮政编码,并将其他框绑定到邮政编码上。 - Ryan Knell

0
try the following before saving / validating 

modelCtrl.$setValidity('editable',true);

模型控制器.$setValidity('editable', true);


0

这是另一个使用Twitter的typeahead的值angularjs指令列表:https://github.com/mihaigiurgeanu/lov-typeahead。您可以将其与bootstrap一起使用,也可以不使用bootstrap。

如果您正在使用bower,则可以执行安装:

bower install lov-typeahead --save

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接