Greifen Sie über einen Filter in AngularJS auf Bereichsvariablen zu

74

Ich übergebe datemeinen Wert auf folgende Weise an meinen benutzerdefinierten Filter:

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;
    }
  });

Ich möchte dort auch ein paar Bereichsvariablen einfügen, wie ich es in Direktiven tun kann. Ist dies möglich, ohne diese Variablen explizit als Funktionsargumente übergeben zu müssen?

Sergei Basharov
quelle

Antworten:

123

Anscheinend kannst du.

Normalerweise übergeben Sie Bereichsvariablen als Funktionsparameter an den Filter:

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

Um den aktuellen Bereich weiterzugeben, müssen Sie jedoch Folgendes übergeben this:

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

und thiswird ein Verweis auf den aktuellen Geltungsbereich sein:

Vereinfacht:

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

Warnung:

  1. Seien Sie vorsichtig damit und verwenden Sie den Bereich nur, um die Werte im Filter zu lesen, da Sie sich sonst leicht in der $ Digest-Schleife wiederfinden.
  2. Filter, die eine so "starke" Abhängigkeit (den gesamten Umfang) erfordern, sind in der Regel sehr schwer zu testen.
Stewie
quelle
Danke für die umfassende Antwort. Ich nehme an, ich übergebe diese Variablen besser explizit an den Filter.
Sergei Basharov
Vielen Dank! Für andere, die dies lesen, müssen Sie es nur verwenden, ng-bind-html-unsafewenn Sie HTML übergeben. Außerdem habe ich $scopestattdessen verwendet, scopedamit es innerhalb der Filterfunktion dieselbe ist, wie ich es überall sonst gewohnt bin :)
Wade
Wenn Sie eine Bereichsvariable wirklich aktualisieren müssen, sollten Sie Ihren Filter in die verschieben Controller. Auf diese Weise hat es keine "starke" Abhängigkeit und ist einfacher zu testen. Verwenden Sie einfach $filter('filter')(array, expression, comparator, anyPropertyKey)in derController
Ghiscoding
5

Ich fand, dass thisReferenzen lokal $scope. Ich bin mir nicht sicher, ob dies ein sicherer Zugriff ist.

pavel_karoukin
quelle