20

I try to call the method removePlayer(playerId) if a button gets clicked. But, the method doesn't get called, or at least the statements inside it aren't firing, because I put a console.log() statement at the top.

The console is empty, so I'm really clueless. Here is my code:

Controller:

function appController($scope) {
    $scope.players = [];
    var playercount = 0;

    $scope.addPlayer = function(playername) {

        $scope.players.push({name: playername, score: 0, id: playercount});
        playercount++;
    }

    function getIndexOfPlayerWithId(playerId) {
        for (var i = $scope.players.length - 1; i > -1; i--) {
            if ($scope.players[i].id == playerId)
                return i;
        }
    }

    $scope.removePlayer = function(playerId) {
        console.log("remove");
        var index = getIndexOfPlayerWithId(playerId);
        $scope.players.slice(index, 1);
    }
}
appController.$inject = ['$scope'];

HTML:

...
<table id="players">
        <tr ng-repeat="player in players">
            <td>{{player.name}}</td>
            <td>{{player.score}}</td>
            <td><button ng-click="removePlayer({{player.id}})">Remove</button></td>
        </tr>
    </table>
...
2
  • Why is the player object in the controller, not in the model? Commented Sep 4, 2013 at 11:40
  • I was just trying out AngularJS, just to discover what it was. It wasn't a 'real' project. @LeeGee Commented Sep 5, 2013 at 15:23

3 Answers 3

38

You shouldn't be using curly braces ({{ }}) in the ng-click expression. You should write:

<button ng-click="removePlayer(player.id)">Remove</button>

Sign up to request clarification or add additional context in comments.

3 Comments

Does the new ng-repeat scope just inherit from the parent scope? So the $parent in my answer wouldn't be necessary?
Yes, scopes created by ng-repeat inherit from a parent scope so the $parent reference is not needed. In fact one should rather avoid using $parent since it strongly links expressions in the event handlers with the template structure (it is enough to insert another scope-creating directive and things might break).
Thanks, that all makes sense. I just remember seeing places that were using $parent in an ng-repeat, and was thinking this was the issue. +1 to you.
4

ng-repeat creates a new scope, so it doesn't know what removePlayer is. You should be able to do something like this:

<table id="players">
    <tr ng-repeat="player in players">
        <td>{{player.name}}</td>
        <td>{{player.score}}</td>
        <td><button ng-click="$parent.removePlayer({{player.id}})">Remove</button></td>
    </tr>
</table>

See https://groups.google.com/forum/?fromgroups=#!topic/angular/NXyZHRTAnLA

2 Comments

Wow, I didn't know about this. Trying now!
Can you create a jsFiddle that recreates the problem? That'll make it easier to diagnose the exact problem. Also, I just noticed the {{}} in the call to the function. I believe you don't need those when calling the function.
-1

As stated, ng-repeat creates it's own scope, and the outer controller scope is not available. But since in JS you are using true objects write something like this:

<tr ng-repeat="player in players">
    <td>{{player.name}}</td>
    <td>{{player.score}}</td>
    <td><button ng-click="player.removePlayer()">Remove</button></td>
</tr>

Beforehand, somewhere on your controller initialization you can assing the "removePlayer" function to each of your player object and naturally code in anything you want, thus accessing outer controller indirectly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.