sna*_*ggs 14 angularjs angular-material
我有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>
Run Code Online (Sandbox Code Playgroud)
与指令:ng-enter.
我的目标:当用户按下时Enter我想隐藏md-autocomplete-suggestions下拉列表
我从HTML中知道我需要以某种方式调用:$mdAutocompleteCtrl.hidden = true;但不知道如何$mdAutocompleteCtrl在Controller中使用.
我用Google搜索并发现:
$timeout( function() { $scope.$$childHead.$mdAutocompleteCtrl.hidden = true; },100);
Run Code Online (Sandbox Code Playgroud)
但没有$mdAutocompleteCtrl(至少在我的JS中,只在HTML中,我不知道它的范围)
我玩这个例子:输入'a'并在下拉列表后按Enter键.
有任何想法吗?
Jam*_*mes 20
它$mdAutocompleteCtrl作为属性放置在自动填充的范围内.
首先,您需要访问自动完成元素.一种方法是在自动完成上放置一个ID:
<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">
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用该元素来获取自动完成的内部范围.由于autocomplete元素本身位于您提供的范围内,因此您需要获取其中一个autocomplete的子元素的范围.
$scope.presEnter = function(e){
var autoChild = document.getElementById('Auto').firstElementChild;
var el = angular.element(autoChild);
el.scope().$mdAutocompleteCtrl.hidden = true;
};
Run Code Online (Sandbox Code Playgroud)
这是一个工作示例:http://codepen.io/anon/pen/rVPZNN#editors=101
DRo*_*son 10
TLDR:触发的示例代码隐藏http://codepen.io/anon/pen/mJvGzp?editors=101
问题:
首先,"Angular Way"建议应避免在Controller中操纵指令.Controller应该基本上只检索(通过服务等)并提供构建视图所需的数据; 它通常应该避免关心这些视图的实现方式(即它应该知道不会使用哪些指令).这有很多很好的理由,一个可能是当你想要修改视图时,它会让生活变得更加容易,例如交换指令.
如果指令确实需要手动修改,最好从另一个指令执行此操作.这允许更大的灵活性,并在以后简化重构(相同的示例:如果交换不同的自动完成指令).
此外,虽然在这种情况下它似乎是解决问题的唯一方法,但$scope.$$childHead.$mdAutocompleteCtrl.hidden代码看起来相当hacky - 除非没有其他选择,否则应该避免访问属性$$,并避免修改兄弟指令而不通过共享范围属性.
不幸的是,在深入挖掘源代码(在主分支上)之后,我找不到任何更好的方法来触发隐藏功能,而不是(如你所建议的)抓住它的范围并修改hidden属性.
通过Controller访问它的另一个问题是它有点困难,因为它通过其他一些范围嵌套.你可以传递事件,获取DOM节点,然后调高它的范围,但这在Controller中是很多不相关的东西.
解决方案:
因此,我们可以添加一个兄弟指令,类似于ngEnter您在Codepen示例中包含的示例指令.也许是一些更明确的东西,以便它更明显地在做什么:
.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();
}
});
};
});
Run Code Online (Sandbox Code Playgroud)
HTML相关时只包含此指令:
<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>
Run Code Online (Sandbox Code Playgroud)
以下是使用它进行修改的示例:http://codepen.io/anon/pen/mJvGzp?edit = 101