web-dev-qa-db-fra.com

Accéder aux variables de la portée à partir d'un filtre dans AngularJS

Je transmets la valeur date à mon filtre personnalisé de la manière suivante:

angular.module('myapp').
  filter('filterReceiptsForDate', function () {
    return function (input, date) {
      var out = _.filter(input, function (item) {
        return moment(item.value.created).format('YYYY-MM-DD') == date;
      });
      return out;
    }
  });

J'aimerais aussi y introduire quelques variables de portée, comme ce que je peux faire dans les directives. Est-ce possible de le faire sans avoir à passer explicitement ces vars comme arguments de fonction?

74
Sergei Basharov

Apparemment tu peux.

Habituellement, vous transmettez des variables d’étendue au filtre en tant que paramètre de fonction:

function MyCtrl($scope){
  $scope.currentDate = new Date();
  $scope.dateFormat = 'short';
}
<span ng-controller="MyCtrl">{{currentDate | date:dateFormat}}</span> // --> 7/11/13 4:57 PM

Mais, pour passer l'étendue actuelle, vous devez passer this:

<span ng-controller="MyCtrl">{{currentDate | date:this}}</span>

et this sera une référence à la portée actuelle:

Simplifié:

app.controller('AppController',
    function($scope) {
      $scope.var1 = 'This is some text.';
      $scope.var2 = 'And this is appended with custom filter.';
    }
  );


app.filter('filterReceiptsForDate', function () {
  return function (input, scope) {
    return input + ' <strong>' + scope.var2 + '</strong>';
  };
});
<div ng-bind-html-unsafe="var1 | filterReceiptsForDate:this"></div>
<!-- Results in: "This is some text. <strong>And this is appended with custom filter.</strong>" -->

PLUNKER

Attention:

  1. Soyez prudent avec ceci et utilisez scope uniquement pour lire les valeurs à l'intérieur du filtre, car sinon vous vous retrouverez facilement dans la boucle $ digest.
  2. Les filtres qui nécessitent une telle dépendance "lourde" (toute la portée) ont tendance à être très difficiles à tester.
122
Stewie

J'ai trouvé que this fait référence à local $scope. Pas sûr que ce soit un moyen sûr d'y accéder.

5
pavel_karoukin