7

いくつかのエンティティ (タグ) のリストを表示するために、AngularJS アプリケーションで select2 プラグインを使用します。これは私のテンプレートの一部です:

select.ddlTags(ui-select2="select2Options", multiple, ng-model="link.tags")
      option(ng-repeat="tag in tags", value="{{tag.id}}") {{tag.name}}

これは私のスコープコードの一部です:

$scope.select2Options = {
  formatNoMatches: function(term) {
    var message = '<a ng-click="addTag()">Добавить тэг "' + term + '"</a>'
    console.log(message); 
    return message;
  }
}

タグリストに存在しない新しいタグをすばやく追加できる機能を提供したいと考えています。そのため、formatNoMatches select2 オプションをオーバーライドして、「新しいタグを追加」リンクを表示します。addTag() 関数を $scope からリンクのクリック イベントに適切にバインドするにはどうすればよいですか?

4

2 に答える 2

6

この問題を解決する鍵はformatNoMatches、オプション オブジェクトの関数によって返される HTML で $compile サービスを使用する必要があることです。このコンパイル手順により、マークアップ内の ng-click ディレクティブがスコープに関連付けられます。残念ながら、これは言うは易く行うは難しです。

ここで完全な動作例を見ることができます: http://jsfiddle.net/jLD42/4/

AngularJS が select2 コントロールを監視して検索の結果を監視する方法を私が知っている方法はないため、結果が見つからない場合はコントローラーに通知する必要があります。formatNoMatchesこれは、関数を使用して簡単に実行できます。

$scope.select2Options = {
    formatNoMatches: function(term) {
        console.log("Term: " + term);
        var message = '<a ng-click="addTag()">Add tag:"' + term + '"</a>';
        if(!$scope.$$phase) {
            $scope.$apply(function() {
                $scope.noResultsTag = term;
            });
        }
        return message;
    }
};

この$scope.noResultsTagプロパティは、ユーザーが最後に入力した、一致する値が返されなかった値を追跡します。は AngularJS ダイジェスト ループのコンテキスト外で呼び出される$scope.noResultsTagため、$scope.$apply を使用して への更新をラップする必要があります。formatNoMatches

変更が発生したときにマークアップを監視$scope.noResultsTagしてコンパイルできます。formatNoMatches

$scope.$watch('noResultsTag', function(newVal, oldVal) {
    if(newVal && newVal !== oldVal) {
        $timeout(function() {
            var noResultsLink = $('.select2-no-results');
            console.log(noResultsLink.contents());
            $compile(noResultsLink.contents())($scope);
        });
    }
}, true);

$timeout がそこで何をしているのか疑問に思うかもしれません。formatNoMatchesこれは、マークアップを使用して DOM を更新する select2 コントロールと、そのマークアップをコンパイルしようとするウォッチ関数との間の競合状態を回避するために使用されます。そうしないと、$('.select2-no-results')セレクターが探しているものを見つけられず、コンパイル ステップでコンパイルするものが何もない可能性が高くなります。

タグの追加リンクがコンパイルされると、ディレクティブはコントローラーng-clickで関数を呼び出すことができるようになります。addTagこれは jsFiddle で実際に確認できます。[タグの追加] リンクをクリックすると、select2 コントロールに入力した検索語でタグ配列が更新され、次に select2 コントロールに新しい検索語を入力したときに、マークアップとオプション リストにそれが表示されます。

于 2013-09-05T07:24:32.180 に答える
4

これを参照できます:

HTML

<div ng-controller="MyCtrl">
       <input ng-change="showDialog(tagsSelections)" type="text" ui-select2="tagAllOptions" ng-model="tagsSelections" style="width:300px;" /> 
       <pre> tagsSelection: {{tagsSelections | json}}</pre>        
</div>

JS

var myApp = angular.module('myApp', ['ui.select2']);

function MyCtrl($scope, $timeout) {

    // Initialize with Objects.
    $scope.tagsSelection = [{
        "id": "01",
            "text": "Perl"
    }, {
        "id": "03",
            "text": "JavaScript"
    }];

    $scope.showDialog = function (item) {
        console.log(item); // if you want you can put your some logic.
    };

    $timeout(function () {
        $scope.tagsSelection.push({
            'id': '02',
                'text': 'Java'
        });
    }, 3000);

    $scope.tagData = [{
        "id": "01",
            "text": "Perl"
    }, {
        "id": "02",
            "text": "Java"
    }, {
        "id": "03",
            "text": "JavaScript"
    }, {
        "id": "04",
            "text": "Scala"
    }];

   // to show some add item in good format
    $scope.formatResult = function (data) {
        var markup;
        if (data.n === "new") markup = "<div> <button class='btn-success btn-margin'><i class='icon-plus icon-white'></i> Create :" + data.text + "</button></div>";
        else markup = "<div>" + data.text + "</div>";
        return markup;

    };

    $scope.formatSelection = function (data) {
        return "<b>" + data.text + "</b></div>";
    };

    $scope.tagAllOptions = {
        multiple: true,
        data: $scope.tagData,
        tokenSeparators: [","],
        createSearchChoice: function (term, data) { // this will create extra tags.
            if ($(data).filter(function () {
                return this.v.localeCompare(term) === 0;
            }).length === 0) {
                return {
                    id: term,
                    text: term,
                    n: "new",
                    s: ""
                };
            }
        },
       // initSelection: function(element, callback) { //if you want to set existing tags into select2
   //   callback($(element).data('$ngModelController').$modelValue);
   //  },
        formatResult: $scope.formatResult,
        formatSelection: $scope.formatSelection,
        dropdownCssClass: "bigdrop",
        escapeMarkup: function (m) {
            return m;
        }
    };



};

Working Fiddle :新しいタグをすばやく追加する

于 2013-09-02T07:42:08.143 に答える