uib tpls ngbtypeahead bootstrap angularjs bootstrap-typeahead

angularjs - tpls - ui-select



Usando Bootstrap typeahead con Angular (7)

Aquí hay otro método que he usado. Está sucio también. Este código se puede colocar en su controlador.

$(''#id_of_your_typeahead_input'').change(function(event){ $scope.$apply(function(scope){ scope.your_ng_model = event.target.value; }); $scope.your_ng_click_function(); });

Actualmente estoy desarrollando una aplicación web que utiliza twitter-bootstrap y Angularjs en buena armonía. Sin embargo, tengo problemas con el typeahead y su uso como modelo ng.

Todo funciona bien cuando se escribe, pero cuando selecciono un elemento (una sugerencia), el valor no se refleja en el controlador Angular a menos que cambie el valor del cuadro de texto después de haber seleccionado un valor. Tipo -> Seleccionar -> Tipo funciona. Tipo -> Seleccionar no funciona.

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>

Código angular:

$scope.addAssignment = function(name) { alert(name); return; }

He agregado una función de cambio de ng para verificar cuándo se cambia el valor del modelo. Solo se cambia cuando se escribe manualmente, y NO cuando se selecciona un valor de la lista que aparece en typeahead.

Agradezco cualquier respuesta que pueda ayudar a resolver este problema. ¡Gracias!


Bueno, he creado una solución sucia. Basado en el ejemplo que se encuentra aquí: https://groups.google.com/forum/#!topic/angular/FqIqrs-IR0w/discussion , he creado un nuevo módulo para el control de 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

Tuve algunos problemas con el enlace de datos, las opciones de autocompletar se obtuvieron de un control angular y tuve el problema de que el control se creó antes de que esta información estuviera lista. Por lo tanto, agregué un atributo html (fuente de datos) al control typeahead y configuré una función $ observe en el constructor.

<typeahead id="addSupplier" model="addSupplier" placeholder="Skriv inn leverandør" class="typeahead" source="getSuppliers()" ></typeahead>

Creo que esta es una solución sucia, por lo que si alguien tiene una mejor idea, puedo escucharla :). El error se describe aquí: https://github.com/angular/angular.js/issues/1284


Esto se basa en la implementación de @zgohr

$(''#your-input-id-here'').change((event)-> angular.element("#your-input-id-here").scope().$apply((scope)-> scope.your_ng_model = event.target.value ) )



Hice esta implementación nativa de typeahead confiando solo en angular (y bootstrap css para el estilo), podría ayudar a cualquiera que busque cómo hacer esto.

Demostración aquí: https://jsfiddle.net/bh29tesc/

Directiva 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)) } } }]);

Uso:

<input class="form-control" type="text" autocomplete="false" ng-model="input" placeholder="Start typing a country" typeahead="countries" typeahead-callback="callback" />


Otra alternativa

En 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>

En su controlador

$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 }


Sugeriría revisar la directiva de typeahead del repositorio de AngularUI / boostrap: http://angular-ui.github.com/bootstrap/

Es una implementación nativa en AngularJS puro, por lo que no requiere ninguna dependencia de terceros. Además de esto, está muy bien integrado con el ecosistema de AngularJS, ya que: * usa la sintaxis concisa conocida de la directiva select * entiende que las promesas de AngularJS permiten que los resultados se puedan obtener dinámicamente usando $http con el mínimo esfuerzo.