J'ai md-autocomplete
:
<md-autocomplete
md-min-length="1"
ng-enter="presEnter();"
md-no-cache="true"
md-selected-item="selectedItem"
md-search-text="searchText"
md-items="item in querySearch(searchText)"
md-item-text="item.name"
placeholder="Search for a vegetable">
<span md-highlight-text="searchText">{{item.name}} :: {{item.type}}</span>
</md-autocomplete>
avec directive: ng-enter
.
Mon objectif: Lorsque l'utilisateur appuie sur Enter
Je souhaite masquer md-autocomplete-suggestions
liste déroulante
Je sais que depuis HTML, j’ai besoin d’appeler: $mdAutocompleteCtrl.hidden = true;
mais je ne sais pas comment utiliser $mdAutocompleteCtrl
dans Controller.
J'ai googlé et trouvé:
$timeout( function() { $scope.$$childHead.$mdAutocompleteCtrl.hidden = true; },100);
mais il n'y a pas de $mdAutocompleteCtrl
(du moins dans mon JS, uniquement en HTML et je ne connais pas sa portée)
Je joue avec cet exemple : tapez 'a' et après le menu déroulant, appuyez sur Entrée.
Des idées?
Le $mdAutocompleteCtrl
est placé en tant que propriété sur la portée de la saisie semi-automatique.
Tout d'abord, vous devez avoir accès à l'élément autocomplete. Une façon de faire est de mettre un identifiant sur la saisie semi-automatique:
<md-autocomplete id='Auto'
md-min-length="1"
ng-enter="presEnter();"
md-no-cache="true"
md-selected-item="selectedItem"
md-search-text="searchText"
md-items="item in querySearch(searchText)"
md-item-text="item.name"
placeholder="Search for a vegetable">
Vous pouvez ensuite utiliser cet élément pour obtenir la portée interne de la saisie semi-automatique. Étant donné que l'élément autocomplete lui-même se trouve dans la portée que vous avez fournie, vous souhaiterez obtenir la portée de l'un des éléments enfants de cette dernière.
$scope.presEnter = function(e){
var autoChild = document.getElementById('Auto').firstElementChild;
var el = angular.element(autoChild);
el.scope().$mdAutocompleteCtrl.hidden = true;
};
Voici un exemple de travail: http://codepen.io/anon/pen/rVPZKN?editors=101
TLDR: Exemple de code qui déclenche hide http://codepen.io/anon/pen/mJvGzp?editors=101
Les problèmes):
Tout d’abord, la «Voie angulaire» suggère d’éviter de manipuler les directives de votre contrôleur. Le contrôleur doit essentiellement extraire (via Services, etc.) et fournir les données nécessaires à la création d’une vue; généralement, il faut éviter de se soucier de la manière dont ces vues sont mises en œuvre (c’est-à-dire qu’il ne doit pas savoir quelles directives seront utilisées). Il y a diverses bonnes raisons à cela. L'une d'entre elles est peut-être que cela simplifie la vie beaucoup plus facilement lorsque vous souhaitez modifier la vue, telle que l'échange de directives.
Si les directives doivent vraiment être modifiées manuellement, il est préférable de le faire à partir d'une autre directive. Cela permet plus de flexibilité et simplifie la refactorisation ultérieurement (même exemple: si vous échangez des directives de complétion automatique différentes).
De plus, bien que cela semble être le seul moyen de résoudre le problème dans ce cas, le code $scope.$$childHead.$mdAutocompleteCtrl.hidden
semble assez compliqué - à moins qu'il n'y ait pas d'autre choix, il faut éviter d'accéder aux propriétés commençant par $$
, ainsi que de modifier les directives sœurs sans le faire via les propriétés de portée partagée.
Malheureusement, après avoir fouillé dans le code source (sur la branche master ), je n’ai trouvé aucun moyen plus agréable de déclencher la fonction de masquage que (comme vous l’avez suggéré) de saisir sa portée et de modifier la propriété hidden
.
Un autre problème pour y accéder via le contrôleur est que c'est un peu plus difficile car il est imbriqué dans quelques autres domaines. Vous pouvez transmettre l'événement, saisir le nœud DOM et extraire sa portée, mais il y a beaucoup de choses non pertinentes dans un contrôleur.
La solution:
Au lieu de cela, nous pouvons ajouter une directive frère, similaire à la directive exemple ngEnter
que vous avez incluse dans l'exemple Codepen. Peut-être quelque chose d'un peu plus explicite pour que ce que cela fait soit un peu plus évident:
.directive('mdHideAutocompleteOnEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if(event.which === 13) {
scope.$apply(function (){
scope.$$childHead.$mdAutocompleteCtrl.hidden = true; // $scope modified to scope
});
event.preventDefault();
}
});
};
});
Le code HTML inclurait simplement cette directive, le cas échéant:
<md-autocomplete
md-hide-autocomplete-on-enter
md-items="item in querySearch(searchText)"
md-item-text="item.name">
<span md-highlight-text="searchText">{{item.name}} :: {{item.type}}</span>
</md-autocomplete>
Voici l'exemple, modifié avec lui en action: http://codepen.io/anon/pen/mJvGzp?editors=101
Je pense que cette solution est meilleure parce que:
il utilise une directive à la place du contrôleur.
c'est plus simple que l'autre solution de directive donnée.
Javascript
app.directive('closeOnEnter', function($compile) {
return {
restrict: 'A',
require: 'mdAutocomplete',
link: function(scope, element) {
element.on('keydown keypress', function($event) {
// 13: Enter
if ($event.keyCode == 13) {
var eAcInput = this.getElementsByTagName('input')[0];
eAcInput.blur();
}
});
},
};
});
HTML
<md-autocomplete close-on-enter ... ...>
Le meilleur moyen d'accéder aux méthodes du contrôleur consiste à cibler l'élément, puis à utiliser l'objet jqLite pour accéder au contrôleur:
var $acElement = angular.element(document.getElementById('Auto'));
var acCtrl = $acElement.controller('mdAutocomplete');
acCtrl.hidden = true;
Chaque fois que vous accédez à quelque chose à l'aide de la méthode scope()
sur un élément angulaire, votre implémentation sera interrompue si vous souhaitez désactiver les informations de débogage angulaire.
Si cela ne vous dérange pas de perdre le focus sur l'élément d'entrée md-autocomplete lors de la saisie, vous pouvez fermer les suggestions md-autocomplete sans utiliser des méthodes compliquées qui impliquent de jouer avec le contrôleur interne $mdAutocompleteCtrl
. Cela dépend de md-autocomplete pour masquer automatiquement les suggestions lorsque l'élément en entrée n'est plus activé.
ng-enter
) et ajoutez un ID à l'élément en entrée à l'aide de md-input-id
<form ng-submit="vm.handleFormSubmit()">
<md-autocomplete md-input-id="autocomplete" ...>
</md-autocomplete>
</form>
blur()
sur l'élément d'entrée #autocomplete
handleFormSubmit() {
angular.element(document.querySelector('#autocomplete')).blur();
}