@@ -17,7 +17,7 @@ no connection between the controller and the view.
1717
1818
1919<doc:example>
20- <doc:source>
20+ <doc:source>
2121 <script>
2222 function TicTacToeCntl($location){
2323 this.$location = $location;
@@ -34,8 +34,8 @@ no connection between the controller and the view.
3434 }
3535 TicTacToeCntl.prototype = {
3636 dropPiece: function(row, col) {
37- if (!this.winner && !this.board) {
38- this.board = this.nextMove;
37+ if (!this.winner && !this.board[row][col] ) {
38+ this.board[row][col] = this.nextMove;
3939 this.nextMove = this.nextMove == 'X' ? 'O' : 'X';
4040 this.setUrl();
4141 }
@@ -51,15 +51,15 @@ no connection between the controller and the view.
5151 this.setUrl();
5252 },
5353 grade: function(){
54- var b = this.board;
55- this.winner =
56- row(0) || row(1) || row(2) ||
57- col(0) || col(1) || col(2) ||
58- diagonal(-1) || diagonal(1);
59- function row(r ) { return same(b, b, b);}
60- function col(c ) { return same(b, b, b);}
61- function diagonal(i) { return same(b[1-i], b, b[1+i]);}
62- function same(a, b, c) { return (a==b && b==c) ? a : '';};
54+ var b = this.board;
55+ this.winner =
56+ row(0) || row(1) || row(2) ||
57+ col(0) || col(1) || col(2) ||
58+ diagonal(-1) || diagonal(1);
59+ function row(row ) { return same(b[row][0] , b[row][1] , b[row][2] );}
60+ function col(col ) { return same(b[0][col] , b[1][col] , b[2][col] );}
61+ function diagonal(i) { return same(b[0][ 1-i], b[1][1] , b[2] [1+i]);}
62+ function same(a, b, c) { return (a==b && b==c) ? a : '';};
6363 },
6464 setUrl: function(){
6565 var rows = [];
@@ -68,12 +68,12 @@ no connection between the controller and the view.
6868 });
6969 this.$location.hashSearch.board = rows.join(';') + '/' + this.nextMove;
7070 },
71- readUrl: function(scope, value) {
71+ readUrl: function(value) {
7272 if (value) {
7373 value = value.split('/');
74- this.nextMove = value;
75- angular.forEach(value.split(';'), function(row, i ){
76- this.board = row.split(',');
74+ this.nextMove = value[1] ;
75+ angular.forEach(value[0] .split(';'), function(row, col ){
76+ this.board[col] = row.split(',');
7777 }, this);
7878 this.grade();
7979 } else {
@@ -82,36 +82,38 @@ no connection between the controller and the view.
8282 }
8383 };
8484 </script>
85+
86+
8587 <h3>Tic-Tac-Toe</h3>
8688 <div ng:controller="TicTacToeCntl">
8789 Next Player: {{nextMove}}
8890 <div class="winner" ng:show="winner">Player {{winner}} has won!</div>
89- <table class="board">
90- <tr ng:repeat="row in board" style="height:15px;">
91- <td ng:repeat="cell in row" ng:style="cellStyle"
92- ng:click="dropPiece($parent.$index, $index)">{{cell}}</td>
93- </tr>
94- </table>
95- <button ng:click="reset()">reset board</button>
91+ <table class="board">
92+ <tr ng:repeat="row in board" style="height:15px;">
93+ <td ng:repeat="cell in row" ng:style="cellStyle"
94+ ng:click="dropPiece($parent.$index, $index)">{{cell}}</td>
95+ </tr>
96+ </table>
97+ <button ng:click="reset()">reset board</button>
9698 </div>
97- </doc:source>
98- <doc:scenario>
99- it('should play a game', function(){
100- piece(1, 1);
101- expect(binding('nextMove')).toEqual('O');
102- piece(3, 1);
103- expect(binding('nextMove')).toEqual('X');
104- piece(1, 2);
105- piece(3, 2);
106- piece(1, 3);
107- expect(element('.winner').text()).toEqual('Player X has won!');
108- });
109-
110-
111- function piece(row, col) {
112- element('.board tr:nth-child('+row+') td:nth-child('+col+')').click();
113- }
114- </doc:scenario>
99+ </doc:source>
100+ <doc:scenario>
101+ it('should play a game', function(){
102+ piece(1, 1);
103+ expect(binding('nextMove')).toEqual('O');
104+ piece(3, 1);
105+ expect(binding('nextMove')).toEqual('X');
106+ piece(1, 2);
107+ piece(3, 2);
108+ piece(1, 3);
109+ expect(element('.winner').text()).toEqual('Player X has won!');
110+ });
111+
112+
113+ function piece(row, col) {
114+ element('.board tr:nth-child('+row+') td:nth-child('+col+')').click();
115+ }
116+ </doc:scenario>
115117</doc:example>
116118
117119
@@ -123,13 +125,12 @@ no connection between the controller and the view.
123125* The controller is defined in JavaScript and has no reference to the rendering logic.
124126* The controller is instantiated by <angular/> and injected into the view.
125127* The controller can be instantiated in isolation (without a view) and the code will still execute.
126- This makes it very testable.
128+ This makes it very testable.
127129* The HTML view is a projection of the model. In the above example, the model is stored in the
128- board variable.
130+ board variable.
129131* All of the controller's properties (such as board and nextMove) are available to the view.
130132* Changing the model changes the view.
131133* The view can call any controller function.
132134* In this example, the `setUrl()` and `readUrl()` functions copy the game state to/from the URL's
133- hash so the browser's back button will undo game steps. See deep-linking. This example calls
134- {@link api/angular.scope.$watch $watch()} to set up a listener that invokes `readUrl()` when
135- needed.
135+ hash so the browser's back button will undo game steps. See deep-linking. This example calls {@link
136+ api/angular.scope.$watch $watch()} to set up a listener that invokes `readUrl()` when needed.
0 commit comments