`this` is undefined in Angular filter function used by ng-repeat

时间:2016-10-19 15:51:19

标签: angularjs angularjs-ng-repeat this ng-repeat angularjs-filter

I'm trying to filter an an array in the dom that uses ng-repeat. The filter works when I hard code the return, but when I try to use this, it gives me the error

Cannot read property minHeight of undefined.

So for some reason this is undefined, but it works in other functions in the controller. I'm not sure why it doesn't work in the filter.

I'm sure I'm missing something ridiculously simple, but I cannot find it

Controller

export class ItemComponent {

    /*@ngInject*/
    constructor($http) {
        this.$http = $http;
        this.minHeight = 0;
    }

   filter(row){
       console.log(this.minHeight);
       return row.minHeight > this.minHeight;
   }

HTML

ng-repeat="item in itemCtrl.items | filter: itemCtrl.filter"

Transpiled Code (from app.bundle.js in browser)

var ItemsComponent = exports.ItemsComponent = function () {
  /*@ngInject*/
  ItemsComponent.$inject = ['$http'];
  function ItemsComponent($http) {
    _classCallCheck(this, ItemsComponent);

    this.$http = $http;
    this.minHeight = 0;
  }

  _createClass(ItemsComponent, [{
    key: '$onInit',
    value: function $onInit() {
      this.loadItems();
    }
  }, {
    key: 'loaditems',
    value: function loadItems() {
      var _this = this;

      this.$http.get('/api/items').then(function (res) {
        _this.items = res.data;
        console.log(_this.items);
      }).catch(function (err) {
        console.log(err);
      });
    }
  }, {
    key: 'filter',
    value: function filter(row) {
      console.log(this.minHeight);

      return row.minHeight > 3;
    }
  }]);

  return ItemsComponent;
}();

2 个答案:

答案 0 :(得分:1)

我很确定这不是最好的方法,但由于没有答案,我可以用这种方式解决问题,我会与你分享。

this上调用时,过滤器函数中没有ng-repeat上下文(为什么?),所以我解决了绑定上下文并从this上下文获取控制器上下文的问题。

HTML

ng-repeat="item in itemCtrl.items | filter: itemCtrl.filter.bind(this)"

控制器

filter(row) {
  console.log(this.itemCtrl.minHeight);
}

答案 1 :(得分:-1)

看起来你想出来了,但是如果你不想在模板文件中绑定,并且我更喜欢在模板文件中尽可能少地放入,你可以在构造函数中绑定类定义。

例如:

export class ItemComponent {
    /*@ngInject*/
    constructor($http) {
        this.$http = $http;
        this.minHeight = 0;

        // arrow function will bind the 'this' you need, or you could use '.bind' instead
        this.filter = (row) => {
            console.log(this.minHeight);
            return row.minHeight > this.minHeight;
       }
    }