angular.js/src/ng/directive/ngController.js
Misko Hevery cd38cbf975 feat(controller): support as instance syntax
Support ng-controller="MyController as my" syntax
which publishes the controller instance to the
current scope.

Also supports exporting a controller defined with route:
````javascript
angular.module('routes', [], function($routeProvider) {
  $routeProvider.when('/home', {controller: 'Ctrl as home', templateUrl: '...'});
});
````
2013-04-22 23:28:41 -07:00

171 lines
6.4 KiB
JavaScript

'use strict';
/**
* @ngdoc directive
* @name ng.directive:ngController
*
* @description
* The `ngController` directive assigns behavior to a scope. This is a key aspect of how angular
* supports the principles behind the Model-View-Controller design pattern.
*
* MVC components in angular:
*
* * Model — The Model is data in scope properties; scopes are attached to the DOM.
* * View — The template (HTML with data bindings) is rendered into the View.
* * Controller — The `ngController` directive specifies a Controller class; the class has
* methods that typically express the business logic behind the application.
*
* Note that an alternative way to define controllers is via the {@link ng.$route $route} service.
*
* @element ANY
* @scope
* @param {expression} ngController Name of a globally accessible constructor function or an
* {@link guide/expression expression} that on the current scope evaluates to a
* constructor function. The controller instance can further be published into the scope
* by adding `as localName` the controller name attribute.
*
* @example
* Here is a simple form for editing user contact information. Adding, removing, clearing, and
* greeting are methods declared on the controller (see source tab). These methods can
* easily be called from the angular markup. Notice that the scope becomes the `this` for the
* controller's instance. This allows for easy access to the view data from the controller. Also
* notice that any changes to the data are automatically reflected in the View without the need
* for a manual update. The example is included in two different declaration styles based on
* your style preferences.
<doc:example>
<doc:source>
<script>
function SettingsController() {
this.name = "John Smith";
this.contacts = [
{type: 'phone', value: '408 555 1212'},
{type: 'email', value: 'john.smith@example.org'} ];
};
SettingsController.prototype.greet = function() {
alert(this.name);
};
SettingsController.prototype.addContact = function() {
this.contacts.push({type: 'email', value: 'yourname@example.org'});
};
SettingsController.prototype.removeContact = function(contactToRemove) {
var index = this.contacts.indexOf(contactToRemove);
this.contacts.splice(index, 1);
};
SettingsController.prototype.clearContact = function(contact) {
contact.type = 'phone';
contact.value = '';
};
</script>
<div ng-controller="SettingsController as settings">
Name: <input type="text" ng-model="settings.name"/>
[ <a href="" ng-click="settings.greet()">greet</a> ]<br/>
Contact:
<ul>
<li ng-repeat="contact in settings.contacts">
<select ng-model="contact.type">
<option>phone</option>
<option>email</option>
</select>
<input type="text" ng-model="contact.value"/>
[ <a href="" ng-click="settings.clearContact(contact)">clear</a>
| <a href="" ng-click="settings.removeContact(contact)">X</a> ]
</li>
<li>[ <a href="" ng-click="settings.addContact()">add</a> ]</li>
</ul>
</div>
</doc:source>
<doc:scenario>
it('should check controller', function() {
expect(element('.doc-example-live div>:input').val()).toBe('John Smith');
expect(element('.doc-example-live li:nth-child(1) input').val())
.toBe('408 555 1212');
expect(element('.doc-example-live li:nth-child(2) input').val())
.toBe('john.smith@example.org');
element('.doc-example-live li:first a:contains("clear")').click();
expect(element('.doc-example-live li:first input').val()).toBe('');
element('.doc-example-live li:last a:contains("add")').click();
expect(element('.doc-example-live li:nth-child(3) input').val())
.toBe('yourname@example.org');
});
</doc:scenario>
</doc:example>
<doc:example>
<doc:source>
<script>
function SettingsController($scope) {
$scope.name = "John Smith";
$scope.contacts = [
{type:'phone', value:'408 555 1212'},
{type:'email', value:'john.smith@example.org'} ];
$scope.greet = function() {
alert(this.name);
};
$scope.addContact = function() {
this.contacts.push({type:'email', value:'yourname@example.org'});
};
$scope.removeContact = function(contactToRemove) {
var index = this.contacts.indexOf(contactToRemove);
this.contacts.splice(index, 1);
};
$scope.clearContact = function(contact) {
contact.type = 'phone';
contact.value = '';
};
}
</script>
<div ng-controller="SettingsController">
Name: <input type="text" ng-model="name"/>
[ <a href="" ng-click="greet()">greet</a> ]<br/>
Contact:
<ul>
<li ng-repeat="contact in contacts">
<select ng-model="contact.type">
<option>phone</option>
<option>email</option>
</select>
<input type="text" ng-model="contact.value"/>
[ <a href="" ng-click="clearContact(contact)">clear</a>
| <a href="" ng-click="removeContact(contact)">X</a> ]
</li>
<li>[ <a href="" ng-click="addContact()">add</a> ]</li>
</ul>
</div>
</doc:source>
<doc:scenario>
it('should check controller', function() {
expect(element('.doc-example-live div>:input').val()).toBe('John Smith');
expect(element('.doc-example-live li:nth-child(1) input').val())
.toBe('408 555 1212');
expect(element('.doc-example-live li:nth-child(2) input').val())
.toBe('john.smith@example.org');
element('.doc-example-live li:first a:contains("clear")').click();
expect(element('.doc-example-live li:first input').val()).toBe('');
element('.doc-example-live li:last a:contains("add")').click();
expect(element('.doc-example-live li:nth-child(3) input').val())
.toBe('yourname@example.org');
});
</doc:scenario>
</doc:example>
*/
var ngControllerDirective = [function() {
return {
scope: true,
controller: '@'
};
}];