I have md-autocomplete
:
TLDR: Example code that triggers hide http://codepen.io/anon/pen/mJvGzp?editors=101
The Problem(s):
First off, the "Angular Way" suggests that manipulating directives in your Controller should be avoided. The Controller should essentially just retrieve (via Services, etc.) and provide the data required to build a view; it generally should avoid caring about exactly what how those views are implemented (i.e. it should know not what directives will be used). There are various good reasons for this, one might be that it makes life much easier when you want to modify the view, such as swapping out directives.
If directives really need to be manually modified, it's better to do so from another directive. This allows more flexibility, and simplifies refactoring later (same example: if swapping out for different autocomplete directives).
Also, although it seems to be the only way to solve the problem in this case, the $scope.$$childHead.$mdAutocompleteCtrl.hidden
code seems fairly hacky - unless there is no other choice, one should avoid accessing properties starting with $$
, and also avoid modifying sibling directives without doing so via shared scope properties.
Unfortunately, after digging into the source code ( on the master branch ), I could not find any nicer way to trigger the hide function than (as you suggested) to grab it's scope and modify the hidden
property.
Another problem with accessing it via the Controller is that it's a bit more difficult because it's nested through a few other scopes. You can pass the event, grab the DOM node, and pull up it's scope, but that's a lot of irrelevant stuff in a Controller.
The Solution:
So instead, we can add a sibling directive, similar to the ngEnter
example directive that you've included in the Codepen example. Perhaps something a bit more explicit so that it's a bit more obvious what it's doing:
.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();
}
});
};
});
The HTML would simply include this directive when relevant:
{{item.name}} :: {{item.type}}
Here's the example, modified with it in action: http://codepen.io/anon/pen/mJvGzp?editors=101