我目前正在开发一个使用twitter-bootstrap和Angularjs的Web应用程序。但是,我遇到了预先输入并将其用作ng模型的问题。
键入时一切正常,但是当我选择一个项目(建议)时,除非在选择值后更改文本框的值,否则该值不会反映在Angular控制器中。类型 - >选择 - >类型有效。类型 - >选择不起作用。
HTML:
<form ng-submit="addAssignment(assignName)">
<div class="input-append">
<input type="text" placeholder="Type a name" ng-model="assignName" ng-change="dostuff()" data-provide="typeahead" data-source="{{ teamNames }}">
<button class="btn" type="submit">Add</button>
</div>
</form>
角度代码:
$scope.addAssignment = function(name) {
alert(name);
return;
}
我添加了一个ng-change功能,只是为了检查模型值的更改时间。它仅在手动键入时更改,而不是从typeahead上显示的列表中选择值时更改。
我感谢任何可能有助于解决此问题的回复。谢谢!
答案 0 :(得分:22)
我建议从AngularUI / boostrap存储库中查看typeahead指令:http://angular-ui.github.com/bootstrap/
它是纯AngularJS中的本机实现,因此它不需要任何第三方依赖项。除此之外,它与AngularJS生态系统非常完美地集成在一起:
*使用select
指令中已知的简明语法
*了解AngularJS承诺,因此可以使用$http
以最小的努力动态获取结果。
答案 1 :(得分:21)
在AngularStrap中,Bootstrap3中有一个可用的本机实现,它利用AngularJS v1.2 +中的ngAnimate
您可能还想结帐:
答案 2 :(得分:9)
我使这个原生的typeahead实现只依赖于角度(和样式的bootstrap css),可能会帮助任何人看看如何做到这一点。
在这里演示:https://jsfiddle.net/bh29tesc/
Angular指令:
angular.module('app').
directive('typeahead', ['$compile', '$timeout', function($compile, $timeout) {
return {
restrict: 'A',
transclude: true,
scope: {
ngModel: '=',
typeahead: '=',
typeaheadCallback: "="
},
link: function(scope, elem, attrs) {
var template = '<div class="dropdown"><ul class="dropdown-menu" style="display:block;" ng-hide="!ngModel.length || !filitered.length || selected"><li ng-repeat="item in filitered = (typeahead | filter:{name:ngModel} | limitTo:5) track by $index" ng-click="click(item)" style="cursor:pointer" ng-class="{active:$index==active}" ng-mouseenter="mouseenter($index)"><a>{{item.name}}</a></li></ul></div>'
elem.bind('blur', function() {
$timeout(function() {
scope.selected = true
}, 100)
})
elem.bind("keydown", function($event) {
if($event.keyCode == 38 && scope.active > 0) { // arrow up
scope.active--
scope.$digest()
} else if($event.keyCode == 40 && scope.active < scope.filitered.length - 1) { // arrow down
scope.active++
scope.$digest()
} else if($event.keyCode == 13) { // enter
scope.$apply(function() {
scope.click(scope.filitered[scope.active])
})
}
})
scope.click = function(item) {
scope.ngModel = item.name
scope.selected = item
if(scope.typeaheadCallback) {
scope.typeaheadCallback(item)
}
elem[0].blur()
}
scope.mouseenter = function($index) {
scope.active = $index
}
scope.$watch('ngModel', function(input) {
if(scope.selected && scope.selected.name == input) {
return
}
scope.active = 0
scope.selected = false
// if we have an exact match and there is only one item in the list, automatically select it
if(input && scope.filitered.length == 1 && scope.filitered[0].name.toLowerCase() == input.toLowerCase()) {
scope.click(scope.filitered[0])
}
})
elem.after($compile(template)(scope))
}
}
}]);
用法:
<input class="form-control" type="text" autocomplete="false" ng-model="input" placeholder="Start typing a country" typeahead="countries" typeahead-callback="callback" />
答案 3 :(得分:3)
好吧,我创建了一个肮脏的解决方法。基于此处的示例:https://groups.google.com/forum/#!topic/angular/FqIqrs-IR0w/discussion,我为typeahead控件创建了一个新模块:
angular.module('storageApp', []).directive('typeahead', function () {
return {
restrict:'E',
replace:true,
scope:{
model:'=',
source:'&'
},
template:'<input type="text" ng-model="model"/>',
link:function (scope, element, attrs) {
console.log(scope.source);
$(element).typeahead({
source:scope.source,
updater:function (item) {
scope.$apply(read(item));
return item;
}
});
function read(value) {
scope.model = value;
}
} // end link function
}; // end return
}); // end angular function
我遇到了数据绑定的一些问题,自动填充选项是从Angular控件中收集的,我遇到的问题是控件是在此信息准备好之前创建的。因此,我在typeahead控件中添加了一个html属性(datasource),并在构造函数中设置了$ observe函数。
<typeahead id="addSupplier" model="addSupplier" placeholder="Skriv inn leverandør" class="typeahead" source="getSuppliers()" ></typeahead>
我认为这是一个肮脏的解决方案,所以如果有人有更好的想法,我很高兴听到它:)。这里描述了错误:https://github.com/angular/angular.js/issues/1284
答案 4 :(得分:0)
这是我使用的另一种方法。它也很脏。此代码可以在控制器中删除。
$('#id_of_your_typeahead_input').change(function(event){
$scope.$apply(function(scope){
scope.your_ng_model = event.target.value;
});
$scope.your_ng_click_function();
});
答案 5 :(得分:0)
这是基于@ zgohr的实施
$('#your-input-id-here').change((event)->
angular.element("#your-input-id-here").scope().$apply((scope)->
scope.your_ng_model = event.target.value
)
)
答案 6 :(得分:0)
另一种选择
在HTML中
<form ng-submit="submitRegion()">
<input type="text" ng-model="currentRegion" id="region-typeahead" data-source="{{ defaultRegions }}" data-provide="typeahead"/>
<button type="submit" class="btn">Add</button>
</form>
在您的控制器
中 $scope.defaultRegions = ["Afghanistan", "Australia", "Bahrain", "New Zealand" ];
$scope.submitRegion = function(){
$scope.currentRegion = $('#region-typeahead').val();
$scope.addRegion(); //your add or click function you defined
$scope.currentRegion = ''; //clear
}