【问题标题】:How to simulate typing in input to make angular filter work如何模拟输入以使角度过滤器工作
【发布时间】:2015-09-14 22:08:53
【问题描述】:

例如,我有<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);
});

所以当我点击字母时,它会将这个字母放入输入字段。但后来什么也没发生...点击的字母出现在输入字段中,但过滤器不起作用。

所以我的问题是,如何使它起作用?当我输入字母时如何模拟输入字段?

非常感谢!

附:这是我的Plunker DEMO

【问题讨论】:

    标签: javascript jquery angularjs input filter


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      什么都没有发生,因为你从未告诉 Angular 模型发生了变化。您正在使用 Angular“世界”之外的普通 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

      【讨论】:

      • 哇!...我无话可说...谢谢您,先生,如此广泛和流行的解释!
      • 我有一个问题要问您,先生:为国家创建单独的控制器并在 ng-controller="CountriesController" 上更改 ng-init 会更好吗? DEMO 第一个解决方案(使用 ng-init="countires=[ '...','...','...' ]")或第二个解决方案(使用 ng-contoller="CountiresContoller")将是后端填写县名更好更容易?在第一个解决方案中,DOM 将是可见的 (
        )...第二个似乎更好更干净...
      猜你喜欢
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多