Angularjs удаляет элементы из области, которые находятся в другой области

Ниже приведен макет того, что у меня есть, используя данные с сайта angular. Цель состоит в том, чтобы удалить все элементы в области 2 (новые устройства), которые уже существуют в области 1 (устройства). У меня есть рабочая модель, но я не считаю, что это лучший метод.

У меня есть контроллер, который извлекает данные из двух разных источников. Для простоты я сделал первую область статической, тогда как вторая будет получать данные через httpget с сайта angular, и это инициируется нажатием кнопки. (Мой код продукта должен использовать кнопку, чтобы я мог вводить переменные в вызов)

app.controller('customersCtrl', function($scope, $http) {

//Example static data for scope 1
$scope.devices = [
   {"Name":"Around the Horn","City":"London","Country":"UK"},
   {"Name":"B's Beverages","City":"London","Country":"UK"},
   {"Name":"Chop-suey Chinese","City":"Bern","Country":"Switzerland"}
];

//scope 2 data from angular example site that is initiated from a button
$scope.loaddata = function() {
  $http.get("http://www.w3schools.com/angular/customers_mysql.php")
    .then(function (response) {
        $scope.newdevices = response.data.records;
      });
  }
});

Затем у меня есть фильтр, который сравнивает области:

app.filter('matcher', function() {
  return function(newdevices, devices) {
    var array2Ids = []
    angular.forEach(devices, function(value, index) {
      array2Ids.push(value.Name);
    })
  return newdevices.filter(function(val) {
    return array2Ids.indexOf(val.Name) === -1;
  })
 }
});

Наконец, я применяю фильтр к своему вызову ng-repeat:

<div ng-app="myApp" ng-controller="customersCtrl">
<button ng-click="loaddata()">load me</button>
  <table>
    <tr ng-repeat="x in newdevices | matcher: devices">
      <td width="300px">{{ x.Name }}</td>
      <td width="150px">{{ x.City }}</td>
      <td width="100px">{{ x.Country }}</td>
    </tr>
  </table>
</div>

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

Я все еще относительно новичок в этом и еще не смог этого достичь.


person Andrew    schedule 04.04.2016    source источник


Ответы (2)


вам не нужен угловой «фильтр». Просто отфильтруйте данные ответа, прежде чем они будут назначены $scope.newdevices. приведенный ниже код был протестирован, но вы поняли идею.

$scope.loaddata = function() {
$http.get("http://www.w3schools.com/angular/customers_mysql.php")
.then(function (response) {
      //do things here, i.e.
       var array2Ids = [];
       angular.forEach(devices, function(value, index) {
         array2Ids.push(value.Name);
       });
       $scope.newdevices = response.data.records.filter(function(val) {
           return array2Ids.indexOf(val.Name) === -1;
       });
    });
}
person sdfacre    schedule 04.04.2016
comment
Это отлично сработало, спасибо. Просто нужно было добавить к устройствам префикс $scope, и это сработало сразу. angular.forEach($scope.devices,.. Одна вещь, которую я сейчас обнаружил, заключается в том, что, поскольку я могу перемещать элементы с новых устройств на устройства, устройства по-прежнему кэшируют данные старой области и не будут отражаться, пока я не обновлю страницу, чтобы принудительно создать новый HTTPget на устройствах. Есть ли способ принудительно перезагрузить область? - person Andrew; 05.04.2016
comment
почти каждое изменение, внесенное в значения области действия, должно автоматически отражаться на странице, что и должно быть двухсторонней привязкой. Но если изменение было сделано за пределами angular, то angular не сможет его обнаружить. Можете ли вы показать мне, как вы перемещали элементы и что вы подразумеваете под устройствами, которые все еще кэшируют данные старой области? - person sdfacre; 06.04.2016

Контроллеры и службы могут получать фильтры с помощью службы $filter.

var matcherFn = $filter('matcher');

var result = marcherFn(newdevices, devices);

Фильтры AngularJS можно использовать как в шаблонах, так и в JavaScript.

Пример в документах:

angular.module('filterExample', [])
.controller('MainCtrl', function($scope, $filter) {
  $scope.originalText = 'hello';
  $scope.filteredText = $filter('uppercase')($scope.originalText);
});

Для получения дополнительной информации см. Справочник по API службы AngularJS $filter.

person georgeawg    schedule 05.04.2016
comment
Спасибо, я прочитаю об этом, так как теперь вижу несколько целей для этого. - person Andrew; 05.04.2016