Question

I'm trying to create a chess board in Angular and for the most part and moving from success to success. I've created a data structure that represents the starting position and for now my HTML is as simple as what I've pasted below. The associated code for returning a class works, but I'm trying to add an ng-click handler that takes the same arguments (first row only in HTML below; actually equates to first column, or "A" file on chess board).

However the associated Javascript code for ng-click, actions.move() is not being reached. Below the markup I've pasted some of the Javascript, and beneath that some of the generated DOM. What am I doing wrong?

HTML:

<div ng-controller='ChessBoardController'>
  <table>
    <tr ng-repeat="rank in model.board">
      <td ng-class="styles.square($index, 'A')" ng-click="actions.move($index, 'A')"><span ng-bind-html="rank.A"></span></td>
      <td ng-class="styles.square($index, 'B')" ><span ng-bind-html="rank.B"></span></td>
      <td ng-class="styles.square($index, 'C')" ><span ng-bind-html="rank.C"></span></td>
      <td ng-class="styles.square($index, 'D')" ><span ng-bind-html="rank.D"></span></td>
      <td ng-class="styles.square($index, 'E')" ><span ng-bind-html="rank.E"></span></td>
      <td ng-class="styles.square($index, 'F')" ><span ng-bind-html="rank.F"></span></td>
      <td ng-class="styles.square($index, 'G')" ><span ng-bind-html="rank.G"></span></td>
      <td ng-class="styles.square($index, 'H')" ><span ng-bind-html="rank.H"></span></td>
      </td>
    </tr>
  </table>
</div>

Javascript:

$scope.styles = (function() {
    return {
        square: function(index, file) {
            if ((index + (file.charCodeAt() % 2)) % 2) {
              return 'lightSquare';
            }
            else {
              return 'darkSquare';
            }
        }
    }
})();

$scope.actions = (function() {
    return {
        move: function(index, file) {
            console.log(arguments);
        }
    }
});

Generated DOM:

<td ng-class="styles.square($index, 'A')" ng-click="actions.move($index, 'A')" class="darkSquare"><span ng-bind-html="rank.A" class="ng-binding">♖</span></td>
Was it helpful?

Solution

The problem is with your action function:

  • You declared action as a function which returns an object of function properties.
  • It seems like you wanted to create it as IIFE but you missed () at the end.
  • Why do you need to create it as IIEF anyway?
  • Inside ngClick You try to refer to action as an object: actions.
  • If you were to write actions(). then it would work but that's not needed (see solution).
  • Angular.js ($parse) ignores your mistake without telling you anything.
  • Read my answer to understand why angularjs ng-click silently eats errors

Solution:

$scope.actions = {
  move: function(index, file) {
      console.log(arguments);
  }
}

OTHER TIPS

I think the "smallest" fix would be to add the missing "auto-execute" parens at the end of the "actions" definition, like what you have at the end of the "styles" definition. However, the example that Ilan Frumer shows is even simpler, just declare it as an object, not an auto-executing function.

You can append to your a and bing the ng-click event to that button.

<td>
    <button ng-class="styles.square($index, 'A')" ng-click="actions.move($index, 'A')"
          class="darkSquare"><span ng-bind-html="rank.A" class="ng-binding">♖</span>
    </button>
</td>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top