2012-10-01 57 views
19

我目前正在開發一個web應用程序,它使用twitter-bootstrap和Angularjs協調得很好。但是,我對typeahead有問題,並將其用作ng模型。使用Bootstrap typeahead和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-改變功能只是爲了檢查當模型值被改變。只有在手動輸入時纔會更改,而不是在從前面顯示的列表中選擇一個值時。

我很欣賞任何可能有助於解決此問題的答案。謝謝!

+0

一直這個問題得到了解決? –

+0

不幸的是,沒有... –

回答

3

那麼,我已經創建了一個骯髒的解決方法。根據設在這裏的例子:https://groups.google.com/forum/#!topic/angular/FqIqrs-IR0w/discussion,我已經建立了預輸入控制一個新的模塊:

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 

我有一些問題與數據綁定,自動填充選項從一個角度控制聚集,我有在這些信息準備好之前就已經創建了控件。因此,我在typeahead控件中添加了html-attribute(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

+0

你不需要$(元素).whatever你可以只是element.whatever –

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(); 
}); 
+0

雖然髒,但這聽起來最好。 – Hengjie

0

這是基於@ zgohr的實現

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

我建議檢查出從AngularUI /自舉庫中的預輸入指令:http://angular-ui.github.com/bootstrap/

它原產在純AngularJS中實現,所以它不需要任何第三方依賴。除此之外,它與AngularJS生態系統很好地集成在一起,因爲它: *使用select指令中已知的簡明語法 *瞭解AngularJS承諾,因此可以使用$http以最小的努力動態獲取結果。

+0

你可能會使用角度帶,因爲它支持最新版本的angularjs;) – genuinefafa

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

我做了這個本地預輸入實現只在角(對於造型和引導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)) 
     } 
    } 
}]); 

用法:

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

在小提琴上,當你選擇它時,它不會將它分配給ngmodel – gdubs

+0

它將item.name賦值給ngModel。獲取整個對象,如果這是你的意思,使用回調。或者只是修改它分配你需要的任何東西 – ropsnou