2016-07-11 16 views
0

私は、Textdownコントロール用のカスタムAngularJS指示文を持っています。それはエミュレートされたドロップダウンのためのdivのリストを印刷しているng-repeatであり、各項目はng-click機能を持っています。 divがクリックされると、その関数は起動しません。なぜあなたは私を助けることができますか?AngularJS ng-click not firing

Plunkr:https://plnkr.co/edit/vOwtjqltq2WfCM9A0dFJ?p=preview

私が最初にそのコンセプトを聞いたところ、私は覚えていないが、あなたが唯一の1つのアイテムを選択することができますを除いて、それは、StackOverflowのの質問のタグ入力に非常に似ています。その例を見ていない場合は、これまでに入力したものと部分的に一致するフィールドを持つ関連項目を使用して入力を開始すると、ドロップダウンリストを持つテキスト入力です。次に、ユーザーはドロップダウン内の項目をクリックすることができ、それはテキスト入力を満たす。ここで

は、メインページのHTMLです:ここで

<!DOCTYPE html> 
<html ng-app="plunker"> 

<head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script> 
    document.write('<base href="' + document.location + '" />'); 
    </script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.4.7/angular.js" data-semver="1.4.7"></script> 
    <script src="app.js"></script> 
    <script src="textdown.js"></script> 
</head> 

<body ng-controller="MainCtrl"> 
    <p>Hello and welcome to the Textdown example!</p> 
    <label>City: 
    <textdown input-placeholder-text="Select a City..." is-editable="true" items="cities" ng-model="selectedCity" title="Name" width="150px"></textdown> 
    </label> 
</body> 

</html> 

は、ディレクティブのHTMLです:ここで

var HYG_TEXTBOX_DROPDOWN_TEMPLATE = '\ 
<div class="hyg-textdown-container activate-textdown" \ 
    ng-class="{ \'hyg-focused\': isFocused() }"> \ 
    <input type="search" class="activate-textdown" placeholder="{{ inputPlaceholderText }}" style="width: 100%;" \ 
     ng-class="{ \'invalid\': !isValid() }" \ 
     ng-change="onInputChanged()" \ 
     ng-focus="onInputFocus($event)" \ 
     ng-model="input" \ 
     ng-blur="onInputBlur()" \ 
     ng-show="isEditable"> \ 
    </input> \ 
    <div class="hyg-textdown-list activate-textdown" ng-show="selectActive" ng-style="{ top: ytop, left: xleft }" style="z-index:5; width: {{ width }}"> \ 
    <div class="hyg-textdown-listed activate-textdown" \ 
     ng-repeat="item in items | property: title: (ngModel != null ? \'\' : input) | orderBy: title | limitTo:5" \ 
     ng-class="{ \'hyg-textdown-listed-active\': isSelected(item) }" \ 
     ng-click="selectItem(item, $event);"> \ 
     <span class="activate-textdown">{{ item[title] }}</span> \ 
    </div> \ 
    </div> \ 
</div>'; 

は、モジュール、ディレクティブ、コントローラ、および関連するフィルタコードです:

angular.module("hyg.Textdown", []) 
.directive("textdown", ["$compile", "$document", "$filter", "$log", "$timeout", function ($compile, $document, $filter, $log, $timeout) { 
    return { 
    restrict: "E", 
    replace: false, 
    controller: "hygTextdownCtrl", 
    template: function (element, attrs) { 
     return HYG_TEXTBOX_DROPDOWN_TEMPLATE; 
    }, 
    require: "?ngModel", 
    scope: { 
     inputPlaceholderText: "@", 
     isEditable: "=", 
     items: "=", 
     ngModel: "=", 
     title: "@", 
     width: "@" 
    }, 
    link: function (scope, element, attrs) { 
     scope.orderBy = $filter("orderBy"); 

     if (scope.isEditable == null) 
     scope.isEditable = true; 

     $document.bind("click", function (e) { 
     var shouldHideSelectList = !Enumerable.From(e.target.classList).Any(function (x) { return x == "activate-textdown"; }); 

     if (shouldHideSelectList) { 
      $timeout(function() { scope.selectActive = false; }, 0); 
     } 
     }); 

     scope.destroy = function() { 
     if (scope.handler != null) 
      scope.handler(); 
     }; 

     scope.isFocused = function() { 
     return scope.focus; 
     }; 

     scope.isSelectActive = function() { 
     return scope.selectActive; 
     }; 

     scope.isValid = function() { 
     return scope.input == null || scope.input.length == 0 || scope.ngModel != null; 
     }; 

     scope.onInputChanged = function() { 
     var input = scope.input == null ? null : scope.input.toLowerCase(); 
     var item = Enumerable.From(scope.items).Where(function (x) { return x[scope.title].toLowerCase() == input; }).ToArray()[0]; 

     scope.selectItem(item); 
     }; 

     scope.onInputFocus = function ($event) { 
     scope.focus = true; 
     scope.selectActive = true; 
     }; 

     scope.onInputBlur = function() { 
     scope.focus = false; 
     scope.selectActive = false; 
     }; 

     scope.selectItem = function (item, $event) { 
     if (scope.isEditable) { 
      scope.ngModel = item; 

      if (item != null) 
      scope.selectActive = false; 
     } 
     }; 

     scope.isSelected = function (item) { 
     return scope.ngModel == item; 
     }; 

     scope.handler = scope.$watch("ngModel", function() { 
     if(scope.ngModel != null) 
      scope.input = scope.ngModel[scope.title]; 
     }); 
    } 
    } 
}]) 
.controller("hygTextdownCtrl", ["$scope", function ($scope) { 
    $scope.focus = false; 
    $scope.handler = null; 
    $scope.selectActive = false; 
}]) 
.filter("property", ["$filter", function ($filter) { 
    return function (array, propertyString, target) { 
    if (target == null) 
     return array; 

    var matched = []; 
    var toMatch = target.toLowerCase(); 

    angular.forEach(array, function (item) { 
     if (item[propertyString].includes != undefined) { 
     if (item[propertyString].toLowerCase().includes(toMatch)) { 
      matched.push(item); 
     } 
     } 
     else 
     { 
     if (item[propertyString].toLowerCase().indexOf(toMatch) > -1) { 
      matched.push(item); 
     } 
     } 
    }); 

    return matched; 
    } 
}]); 

ありがとう、 ジブバ

+0

at line 47 'Enumerable'は定義されていません。 (プロジェクトにlinq.jsが含まれていてplunkrには含まれていない場合) –

+0

テンプレートからng-blurイベントを削除します。 – JEMI

+0

Davidさん、プロジェクトでlinq.jsを使用していて、正しく設定していませんPlunkr。それをキャッチするためにありがとう。 – JibbaJamba

答えて

2

ng-clickが発砲していないのは、オプションをクリックする前に、入力にblurイベントが発生し、オプションが表示されず、オプションがクリックされないためです。

ng-clickの代わりにng-mousedownを使用してオプションを選択してみてください。

+0

これはうまくいった!しかし、別のディレクティブ(ほぼ同時に複数の項目を選択することができます)でほぼ同じことをやっているので、混乱します。ng-clickで動作します。ブラスト! – JibbaJamba

+0

その作業指令のplunkrを共有してください、私は見ています – Prashant

+0

実際にng-mousedownを使用するように関連する指令を変更しました。関係なく、あなたの助けをありがとう。 – JibbaJamba