20

私は現在、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関数を追加しました。手動で入力した場合にのみ変更され、先行入力に表示されるリストから値が選択された場合は変更されません。

この問題の解決に役立つ可能性のある回答に感謝します。ありがとう!

4

7 に答える 7

22

AngularUI / boostrapリポジトリからtypeaheadディレクティブを確認することをお勧めします:http://angular-ui.github.com/bootstrap/

これは純粋なAngularJSでのネイティブ実装であるため、サードパーティの依存関係は必要ありません。これに加えて、AngularJSエコシステムと非常によく統合されています。*selectディレクティブで知られている簡潔な構文を使用します* AngularJSの約束を理解しているため$http、最小限の労力で動的に結果を取得できます。

于 2013-03-25T13:23:10.823 に答える
21

AngularJS v1.2 +から活用するBootstrap3のAngularStrapには、動作するネイティブ実装があります。ngAnimate

チェックアウトすることもできます。

于 2012-12-26T02:34:59.963 に答える
9

私はこのネイティブの先行入力実装をAngular(およびスタイリング用のブートストラップ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" />
于 2015-06-19T18:56:23.927 に答える
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

データバインディングに問題があり、自動入力オプションがAngularコントロールから収集され、この情報の準備ができる前にコントロールが作成されるという問題がありました。そのため、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

于 2012-10-08T15:54:14.697 に答える
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();
});
于 2012-12-11T20:01:08.737 に答える
0

これは@zgohrの実装に基づいています

$('#your-input-id-here').change((event)->
  angular.element("#your-input-id-here").scope().$apply((scope)->
    scope.your_ng_model = event.target.value
  )
)
于 2013-03-04T08:53:27.147 に答える
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
    }
于 2013-05-28T06:32:36.000 に答える