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

时间:2015-06-28 10:39:23

标签: javascript jquery angularjs input filter

例如,我有国家/地区列表<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>

然后我做了过滤输入:

<input id="q" type="text" ng-model="q"/>

另外,我有字母表:

<ul>
  <li class="letter">A</li>
  <li class="letter">B</li>
  <li class="letter">R</li>
  <li class="letter">U</li>
</ul>

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

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

所以当我点击字母时,它会收到这封信并输入输入字段。但是没有发生任何事情......点击的字母显示在输入字段中,但过滤器不起作用。

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

提前很多!

P.S。这是我的Plunker DEMO

2 个答案:

答案 0 :(得分: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();
});

警告:你应该如何做,避免一定要这样做。

解决方案#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>

并在控制器中:

app.controller('MainController', function($scope) {
    $scope.setTerm = function(letter) {
        $scope.q = letter;
    };
});

演示: 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();
            });
        }
    };
});

并以这种方式使用:

<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>

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

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

答案 1 :(得分:0)

如果您使用的是反应式表单,请尝试FormControl.updateValueAndValidity()