ng-модель не пересчитывает длину массива при одном нажатии клавиши для текстового фильтра

У меня есть таблица, в которой используется отфильтрованная текстовая область для построения отфильтрованной таблицы и вывода количества. ДОМ выглядит следующим образом.

 <div filter-input></div>

 <table>
    <tr ng-repeat='item in filtered=(mySourceJSON | filter:filterInputService.searchText)'></tr>
    .. .. ..
    .. .. ..
 </table>

С вводом фильтра, являющимся директивой:

angular.module('myApp')
.directive('filterInput', function () {
return {
  controller: 'FilterInputCtrl',
  templateUrl: 'views/filter_input.html',
  restrict: 'A',
  link: function(scope, el, attr){
  }
};

});

Со следующим контроллером:

angular.module('myApp')
 .controller('FilterInputCtrl', function ($scope, filterInputService) {
   $scope.filterInputService = filterInputService;
});

И содержимое шаблона:

 <div>
   <span>
    <input  ng-model='filterInputService.searchText'/>
   </span>
   <span>
      Showing {{filtered.length}} / {{gridItems.length}}
   </span>
 </div>

Служба представляет собой простой заполнитель, который устанавливает для searchText значение empty string при инициализации.

Поведение, которое я вижу, выглядит следующим образом:

Когда я ввожу символ в поле ввода фильтра, таблица обновляется и скрывает элементы, не соответствующие фильтру, однако количество отфильтрованных элементов не обновляется до тех пор, пока не будет введен второй символ. Что именно вызывает это? Почему область не обновляется до второго символа? Как этого избежать?


person Abraham P    schedule 15.07.2013    source источник
comment
Кажется, у вас нет проблем с вашим кодом. Он должен работать нормально. Взгляните на этот Plnker. Может быть, вы используете более одного прицела, не так ли?   -  person Caio Cunha    schedule 16.07.2013
comment
Плункер на самом деле демонстрирует такое же поведение. Если вы введете один символ в поле поиска, счетчик останется равным 3. Может ли быть что-то странное с keyUp vs change? НАПРИМЕР. Изучая мой код, я считаю, что фильтр отстает на одно нажатие клавиши.   -  person Abraham P    schedule 16.07.2013
comment
Поместите console.log в свою функцию FilterInputCtrl и посмотрите, сколько раз она появляется в вашей консоли. Более одного раза указывает, что у вас может быть несколько проблем с областью действия. Сколько раз ng-app появляется в вашем HTML?   -  person Code Whisperer    schedule 16.07.2013


Ответы (1)


Вы правы, вы наткнулись на ошибку. Я смотрел на это, и это связано с проблемой в цикле дайджеста, но кажется, что это не очень просто решить, и нестабильная версия уже решает это (откройте файл Plnker и измените версию Angular на 1.1.5, чтобы увидеть).

Поэтому я думаю, что вам лучше всего обойти это, поскольку, вероятно, это не стоит усилий, направленных на устранение этой ошибки для вашей конкретной необходимости. В настоящее время вы устанавливаете от filtered до ng-repeat. Все, что вам нужно сделать, это $watch фильтр и применить фильтр самостоятельно.

В принципе:

Измените привязку на:

<tr ng-repeat='item in filtered'>

Затем в контроллере внедрите службу $filter и сохраните ссылку на коллекцию. фильтр. $watch символы фильтра и создайте массив filtered:

.controller('FilterInputCtrl', function ($scope, $filter, filterInputService) {
  var dfFilter = $filter('filter');

  $scope.filterInputService = filterInputService;

  $scope.$watch('filterInputService.searchText', function(value) {
    $scope.filtered = dfFilter($scope.mySourceJSON, value);
  });
});

Вот рабочий Plnker.

person Caio Cunha    schedule 18.07.2013