如何模拟输入中的输入以使角度过滤器工作

Joh*_*rez 1 javascript jquery input filter angularjs

例如,我有国家列表,<div class="container" ng-init=" countries=['Ukraine','Urugvai','Russia','Romania','Rome','Argentina','Britain'] ">我通过ng-repeat显示它们:

  <ul>
    <li ng-repeat="country in countries | filter:q">{{ country }}</li>
  </ul>
Run Code Online (Sandbox Code Playgroud)

然后我做了过滤输入:

<input id="q" type="text" ng-model="q"/>
Run Code Online (Sandbox Code Playgroud)

另外,我有字母表:

<ul>
  <li class="letter">A</li>
  <li class="letter">B</li>
  <li class="letter">R</li>
  <li class="letter">U</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

我要做的是,当我点击.letter并将这封信输入以开始过滤我的国家列表时收到信件:

$(document).on('click','.letter',function(){
  var el = $(this);
  var html = el.html();
  var firstLetter = html.charAt(0);
  $('#q').val(firstLetter);
});
Run Code Online (Sandbox Code Playgroud)

所以当我点击字母时,它会把这个字母带进输入字段.但是没有发生任何事情......点击的字母显示在输入字段中,但过滤器不起作用.

所以我的问题是,如何使这个工作?当我把信放在那里时如何模拟输入字段中的输入?

Thanx提前很多!

PS这是我的Plunker DEMO

dfs*_*fsq 5

解释和解决方案#1(坏)

没有任何事情发生,因为你从未告诉Angular模型有变化.你正在Angular"world"之外使用plaing Javascript.在这种情况下,您需要手动更新范围并触发摘要循环:

$(document).on('click', '.letter', function() {
    var el = $(this);
    var html = el.html();
    var x = 'some';
    var firstLetter = html.charAt(0);
    //alert(firstLetter);
    $('#q').val(firstLetter);


    var scope = angular.element($('#q')[0]).scope();
    scope.q = firstLetter;
    scope.$apply();
});
Run Code Online (Sandbox Code Playgroud)

警告:但这不是你应该怎么做的,一定要避免这样做.

解决方案#2(更好)

而是使用ngClick指令来更新q模型,您的代码将变得更加清晰.

在HTML中,您将放置ngClick指令:

<ul>
    <li class="letter" ng-click="setTerm('A')">A</li>
    <li class="letter" ng-click="setTerm('B')">B</li>
    <li class="letter" ng-click="setTerm('R')">R</li>
    <li class="letter" ng-click="setTerm('U')">U</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

在控制器中:

app.controller('MainController', function($scope) {
    $scope.setTerm = function(letter) {
        $scope.q = letter;
    };
});
Run Code Online (Sandbox Code Playgroud)

演示: http ://plnkr.co/edit/N0DpH9kNTndo498eempF?p = preview

然而,即使这看起来更接近Angular风格的解决方案,它仍然不理想,因为你需要在每个LI元素上复制ngClick处理程序.在这里,我们可以找到解决此问题的最佳解决方案 - 自定义指令,这是Angular的关键思想之一.

解决方案#3(最好)

您可以创建自定义指令以避免为每个列表项编写相同的ngClick处理程序.它不仅太冗长,而且效率也低,因为每个ngClick都会绑定新的点击事件.

简单的指令看起来像这样:

app.directive('searchList', function() {
    return {
        scope: {
            searchModel: '=model'
        },
        link: function(scope, element, attrs) {
            element.on('click', attrs.searchList, function() {
                scope.searchModel = $(this).text();
                scope.$apply();
            });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

并以这种方式使用:

<ul search-list=".letter" model="q">
    <li class="letter">A</li>
    <li class="letter">B</li>
    <li class="letter">R</li>
    <li class="letter">U</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

这非常灵活(可以与不同的模型一起使用并重复使用,可以与列表中的有限项集(CSS选择器)一起使用)和有效的解决方案(只有一个事件处理程序).

演示: http ://plnkr.co/edit/rZrPheCy6FToWsPRLgAV