diff options
Diffstat (limited to 'docs/content/cookbook/mvc.ngdoc')
| -rw-r--r-- | docs/content/cookbook/mvc.ngdoc | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/docs/content/cookbook/mvc.ngdoc b/docs/content/cookbook/mvc.ngdoc index 470794b8..bc0eb653 100644 --- a/docs/content/cookbook/mvc.ngdoc +++ b/docs/content/cookbook/mvc.ngdoc @@ -3,19 +3,24 @@ @name Cookbook: MVC @description + MVC allows for a clean an testable separation between the behavior (controller) and the view (HTML template). A Controller is just a JavaScript class which is grafted onto the scope of the view. This makes it very easy for the controller and the view to share the model. + The model is simply the controller's this. This makes it very easy to test the controller in isolation since one can simply instantiate the controller and test without a view, because there is no connection between the controller and the view. + + <doc:example> <doc:source> <script> - function TicTacToeCntl(){ + function TicTacToeCntl($location){ + this.$location = $location; this.cellStyle= { 'height': '20px', 'width': '20px', @@ -29,8 +34,8 @@ no connection between the controller and the view. } TicTacToeCntl.prototype = { dropPiece: function(row, col) { - if (!this.winner && !this.board[row][col]) { - this.board[row][col] = this.nextMove; + if (!this.winner && !this.board) { + this.board = this.nextMove; this.nextMove = this.nextMove == 'X' ? 'O' : 'X'; this.setUrl(); } @@ -51,9 +56,9 @@ no connection between the controller and the view. row(0) || row(1) || row(2) || col(0) || col(1) || col(2) || diagonal(-1) || diagonal(1); - function row(r) { return same(b[r][0], b[r][1], b[r][2]);} - function col(c) { return same(b[0][c], b[1][c], b[2][c]);} - function diagonal(i) { return same(b[0][1-i], b[1][1], b[2][1+i]);} + function row(r) { return same(b, b, b);} + function col(c) { return same(b, b, b);} + function diagonal(i) { return same(b[1-i], b, b[1+i]);} function same(a, b, c) { return (a==b && b==c) ? a : '';}; }, setUrl: function(){ @@ -63,12 +68,12 @@ no connection between the controller and the view. }); this.$location.hashSearch.board = rows.join(';') + '/' + this.nextMove; }, - readUrl: function(value) { + readUrl: function(scope, value) { if (value) { value = value.split('/'); - this.nextMove = value[1]; - angular.forEach(value[0].split(';'), function(row, i){ - this.board[i] = row.split(','); + this.nextMove = value; + angular.forEach(value.split(';'), function(row, i){ + this.board = row.split(','); }, this); this.grade(); } else { @@ -102,6 +107,7 @@ no connection between the controller and the view. expect(element('.winner').text()).toEqual('Player X has won!'); }); + function piece(row, col) { element('.board tr:nth-child('+row+') td:nth-child('+col+')').click(); } @@ -109,8 +115,11 @@ no connection between the controller and the view. </doc:example> + + # Things to notice + * The controller is defined in JavaScript and has no reference to the rendering logic. * The controller is instantiated by <angular/> and injected into the view. * The controller can be instantiated in isolation (without a view) and the code will still execute. @@ -122,4 +131,5 @@ no connection between the controller and the view. * The view can call any controller function. * In this example, the `setUrl()` and `readUrl()` functions copy the game state to/from the URL's hash so the browser's back button will undo game steps. See deep-linking. This example calls - {@link angular.scope.$watch $watch()} to set up a listener that invokes `readUrl()` when needed. + {@link api/angular.scope.$watch $watch()} to set up a listener that invokes `readUrl()` when +needed. |
