使用带有Angular的Bootstrap typeahead

Kje*_*eim 20 angularjs bootstrap-typeahead

我目前正在开发一个使用twitter-bootstrap和Angularjs的Web应用程序.但是,我对typeahead有问题并将其用作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>
Run Code Online (Sandbox Code Playgroud)

角度代码:

 $scope.addAssignment = function(name) {
    alert(name);
    return;
 }
Run Code Online (Sandbox Code Playgroud)

我添加了一个ng-change函数,只是为了检查模型值的更改时间.它仅在手动键入时更改,而不是从typeahead上显示的列表中选择值时更改.

我感谢任何可能有助于解决此问题的回复.谢谢!

pko*_*rce 22

我建议从AngularUI/boostrap存储库中查看typeahead指令:http://angular-ui.github.com/bootstrap/

它是纯AngularJS中的本机实现,因此它不需要任何第三方依赖项.除此之外,它与AngularJS生态系统完美集成,因为它:*使用select指令中已知的简明语法*理解AngularJS承诺,因此可以使用$http最小的努力动态获取结果.


Oli*_*ier 21

AngularStrap for Bootstrap3中有一个可用的本机实现,它利用ngAnimate了AngularJS v1.2 +

您可能还想结帐:


rop*_*nou 9

我使这个原生的typeahead实现只依赖于角度(和样式的bootstrap css),可能会帮助任何人看看如何做到这一点.

在这里演示:https://jsfiddle.net/bh29tesc/

角度指令:

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))
        }
    }
}]);
Run Code Online (Sandbox Code Playgroud)

用法:

<input class="form-control" type="text" autocomplete="false" ng-model="input" placeholder="Start typing a country" typeahead="countries" typeahead-callback="callback" />
Run Code Online (Sandbox Code Playgroud)