swang
swang

Reputation: 5249

In what scope is ng-repeat "as alias" available

I'm using angular 1.4.8. I want to save filtered result from ng-repeat and use it to determine whether to enable a "load more" button at the bottom of the list. I have looked at this question:

AngularJS - how to get an ngRepeat filtered result reference

And many others, they suggest to use "as alias" from ng-repeat, here's what my code looks like:

  <ul class="media-list tab-pane fade in active">
    <li class="media">
      <div ng-repeat-start="item in items | limitTo: totalDisplayed as filteredResult">
        {{item}}
      </div>
      <div class="panel panel-default" ng-repeat-end>
      </div>
      <div>
        {{filteredResult.length}}
      </div>
    </li>
  </ul>
  <button ng-click="loadMore()" ng-show="totalDisplayed <= filteredResult.length">
    more
  </button>

However, I found filteredResult.length is displayed fine right after ng-repeat, but the button is never shown. If I try to display filteredResult.length in where the button is, it will show null.

So is there a rule for "as alias" scope? I've seen plenty of examples work but mine doesn't, what am I missing here?

EDIT:

The accepted answer uses controllerAs which indeed will resolve the problem. However, charlietfl's comment using ng-init to save filteredResult to parent scope is also very neat and that's the solution I use in my code eventually.

Upvotes: 2

Views: 5271

Answers (1)

doroshko
doroshko

Reputation: 754

Probably some of classes in your <ul class="media-list tab-pane fade in active"> or <li class="media"> is selector for a directive that would have its own scope. So you store filteredResult in e.g. tab-pane's scope and then try to have access out of it's scope in outside of ul tag.

Try to use Controller as instead of scope:

angular
  .module('plunker', [])
  .controller('MainCtrl', function() {
    vm = this;
    // make an array from 1 to 10
    var arr = [];
    while (arr.length < 10) {
      arr.push(arr.length + 1)
    };

    vm.items = arr;
    vm.totalDisplayed = 5;
    vm.filteredResult = [];
  });

<body ng-controller="MainCtrl as main">
  {{main.items}}
  <ul class="media-list tab-pane fade in active">
    <li class="media">
      <div ng-repeat-start="item in main.items | limitTo: main.totalDisplayed as filteredResult">
        {{item}}
      </div>
      <div class="panel panel-default" ng-repeat-end>
      </div>
      <div>
        filteredResult = {{main.filteredResult = filteredResult}}
      </div>
    </li>
  </ul>
  <button ng-click="loadMore()" ng-show="main.totalDisplayed <= main.filteredResult.length">
    more
  </button>
</body>


http://plnkr.co/edit/drA1gQ1qj0U9VCN4IIPP?p=preview

Upvotes: 1

Related Questions