user2156149
user2156149

Reputation: 53

AngularJS ng-repeat and controllerAs

I using simple syntax to show, hide element in ng-repeat

<div ng-controller='MainController as vm'>
<ul>
  <li ng-repeat="item in vm.items" ng-click="vm.showItem()">
    {{item}}
    <span ng-show="show">test</span>
    </li>
</ul>

When i was using scope everythink worked fine

 $scope.showItem = function(){
   this.show=!this.show; 
 } 

But same code with controllerAs doesn't work

 vm = this; 
 vm.showItem = function(){
    this.show=!this.show;
 }

How can i access to show property of current item in ng-repeat?

Controller as http://plnkr.co/edit/Dbp5fO9OEpV6lFRySYUK?p=preview

$scope http://plnkr.co/edit/ptuySNRXSrA64K1IAng3?p=preview

Upvotes: 0

Views: 183

Answers (4)

Krzysztof Safjanowski
Krzysztof Safjanowski

Reputation: 7438

Proof of concept:

var app = angular.module('myApp', []);

app.controller('MainController', function() {
  vm = this;
  vm.items = [];

  for (var i = 0; i < 10; i++) vm.items.push({
    value: i,
    show: false,
    showItem: function() {
      this.show = !this.show
    }
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="MainController as vm">
    <ul>
      <li ng-repeat="item in vm.items" ng-click="item.showItem()">
        {{item.value}}
        <span ng-show="item.show">test</span>
      </li>
    </ul>
  </div>
</div>

Than we are going to improve it by extracting showItem method to the Item prototype

Second step - using prototype to less memory consume

var app = angular.module('myApp', []);

app.controller('MainController', function() {
  vm = this;
  vm.items = [];

  for (var i = 0; i < 10; i++) vm.items.push(new Item(i));

  function Item(value) {
    this.value = value
    this.show = false
  }

  Item.prototype.showItem = function() {
    this.show = !this.show
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="MainController as vm">
    <ul>
      <li ng-repeat="item in vm.items" ng-click="item.showItem()">
        {{item.value}}
        <span ng-show="item.show">test</span>
      </li>
    </ul>
  </div>
</div>

Next step will be extracting Item to angular factory

Upvotes: 1

S Vinesh
S Vinesh

Reputation: 539

Get the current this instance from the html like

 <li ng-repeat="item in vm.items" ng-click="vm.showItem(this)">

And use it in your controller

vm.showItem = function(_this){
   _this.show=!_this.show;
}

The problem you faced is the change of this context

Updated plunker http://plnkr.co/edit/pkxI68sGMXonDOA49EUq?p=preview

Upvotes: 1

Nitheesh
Nitheesh

Reputation: 20006

Replace the function definition with.

vm.show = !vm.show;

I have attached the sample code snippet.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script data-require="[email protected]" data-semver="1.5.5" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script>
    <script>
        document.write('<base href="' + document.location + '" />');
    </script>
    <script>
        var app = angular.module('myApp', []);


        app.controller('MainController', function () {
            vm = this;
            vm.items = [];
            vm.start = 0;
            vm.end = 20;
            for (var i = 0; i < 10; i++) vm.items.push(i);
            // return vm;
            vm = this;
            vm.show = true;
            vm.showItem = function () {
                vm.show = !vm.show;
            }
        });
    </script>
</head>

<body>

    <div ng-app="myApp">
        <div ng-controller='MainController as vm'>
            <ul>
                <li ng-repeat="item in vm.items" ng-click="vm.showItem()">
                    {{item}}
                    <span ng-show="vm.show">test</span>
                </li>
            </ul>
        </div>
    </div>
</body>

</html>

Upvotes: 0

divsingh
divsingh

Reputation: 1232

You need to use vm.show = !vm.show;

vm = this; 
 vm.showItem = function(){
    vm.show=!vm.show;
 }

Upvotes: 0

Related Questions