У меня есть карта элементов данных, которые я показываю в таблице, которая обновляется с новыми значениями в контроллере (следовательно, трек по ключу). Все это прекрасно работает.
Если я попытаюсь выбросить угловой фильтр в микс, он игнорирует фильтр и отображает все данные.
(BTW, элементы данных заполняются обратным вызовом из данных, поступающих из websocket - возможно, это вызывает проблему)
Что мне здесь не хватает?
<label>Filter by Id <input ng-model="search.id"></label><br>
<table class="table table-striped">
<tr>
<th>Id</th>
<th>type</th>
<th>value</th>
<th>time</th>
</tr>
<tr ng-repeat="item in data | filter:search track by item.key">
<td>{{item.id}}</td>
<td>{{item.type}}</td>
<td>{{item.value}}</td>
<td>{{item.timestamp}}</td>
</tr>
</table>
контроллер:
DataService.addListener(listener);
$scope.data = {};
//incoming data from a websocket
function listener(data) {
var key = data.stuff.id1 + ':' + data.stuff.id2;
var lineItem = {
'id' : data.stuff.id1,
'type' : data.stuff.id2,
'value' : data.data.value,
'timestamp' : new Date(data.stuff.ts).toTimeString(),
'key' :key
};
$scope.$apply(function() {
$scope.data[key] = lineItem;
});
}
обратите внимание, что item.key - это свойство, которое однозначно идентифицирует элемент на карте данных.
Проблема заключается в том, что фильтр не работает на картах. Derp.
Выгравируйте фильтр карты из этого ответа здесь, теперь все работает.
плункер http://plnkr.co/edit/u5D3tGGKDOY4P4u6T1GZ?p=preview
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="[email protected]" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="TestCtrl">
<label>Filter by Id <input ng-model="search.id"></label><br>
<table border="1">
<tr>
<th>Id</th>
<th>value</th>
</tr>
<tr ng-repeat="item in data | mapFilter:search track by item.key">
<td>{{item.id}}</td>
<td>{{item.value}}</td>
</tr>
</table>
</body>
</html>
сценарий:
angular.module('app', []).controller('TestCtrl', function($scope) {
$scope.data = {};
for (var i = 0; i < 20; i++) {
var item = {
id: randomWord() + " " + randomWord(),
key: 'key ' + i,
value: Math.floor(Math.random() * 300),
};
$scope.data[item.key] = item;
}
})
.filter('mapFilter', function($filter) {
var filter = $filter('filter');
return function(map, expression, comparator) {
if (! expression) return map;
var result = {};
angular.forEach(map, function(data, index) {
if (filter([data], expression, comparator).length)
result[index] = data;
});
return result;
}
});
var words = [
'lunville',
'pandybat',
'demurrer',
'slighter',
'reguline',
'exploder',
'krakatoa',
'wirespun',
];
function randomWord() {
return words[ Math.floor(Math.random() * 8)];
}
Вы фильтруете search
а не search.id
так как ваша модель ввода задана как search.id
. Попробуй это:
<tr ng-repeat="item in data | filter:search.id track by item.key">