docs(ngController): add formatting to controller as description and example

Adds to #7591
This commit is contained in:
Peter Bacon Darwin
2014-05-27 22:43:37 +01:00
parent 462eefc1e4
commit 2859fc408e

View File

@@ -34,168 +34,183 @@
* easily be called from the angular markup. Any changes to the data are automatically reflected
* in the View without the need for a manual update.
*
* Two different declaration styles are included below: one which injects `scope` into the
* controller, and another which instead binds methods and properties directly onto the controller
* using `this`. The first option is more common in the Angular community, and is generally used
* in boilerplates and in this guide. However, there are advantages to binding properties directly
* to the controller and avoiding scope. Using `controller as` makes it obvious which controller
* you are accessing in the template when multiple controllers apply to an element. Since there
* is always a `.` in the bindings, you don't have to worry about prototypal inheritance masking
* primitives.
<example>
<file name="index.html">
<script>
function SettingsController1() {
this.name = "John Smith";
this.contacts = [
{type: 'phone', value: '408 555 1212'},
{type: 'email', value: 'john.smith@example.org'} ];
};
SettingsController1.prototype.greet = function() {
alert(this.name);
};
SettingsController1.prototype.addContact = function() {
this.contacts.push({type: 'email', value: 'yourname@example.org'});
};
SettingsController1.prototype.removeContact = function(contactToRemove) {
var index = this.contacts.indexOf(contactToRemove);
this.contacts.splice(index, 1);
};
SettingsController1.prototype.clearContact = function(contact) {
contact.type = 'phone';
contact.value = '';
};
</script>
<div id="ctrl-as-exmpl" ng-controller="SettingsController1 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>
</file>
<file name="protractor.js" type="protractor">
it('should check controller as', function() {
var container = element(by.id('ctrl-as-exmpl'));
expect(container.findElement(by.model('settings.name'))
.getAttribute('value')).toBe('John Smith');
var firstRepeat =
container.findElement(by.repeater('contact in settings.contacts').row(0));
var secondRepeat =
container.findElement(by.repeater('contact in settings.contacts').row(1));
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('408 555 1212');
expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('john.smith@example.org');
firstRepeat.findElement(by.linkText('clear')).click();
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('');
container.findElement(by.linkText('add')).click();
expect(container.findElement(by.repeater('contact in settings.contacts').row(2))
.findElement(by.model('contact.value'))
.getAttribute('value'))
.toBe('yourname@example.org');
});
</file>
</example>
<example>
<file name="index.html">
<script>
function SettingsController2($scope) {
$scope.name = "John Smith";
$scope.contacts = [
{type:'phone', value:'408 555 1212'},
{type:'email', value:'john.smith@example.org'} ];
$scope.greet = function() {
alert($scope.name);
};
$scope.addContact = function() {
$scope.contacts.push({type:'email', value:'yourname@example.org'});
};
$scope.removeContact = function(contactToRemove) {
var index = $scope.contacts.indexOf(contactToRemove);
$scope.contacts.splice(index, 1);
};
$scope.clearContact = function(contact) {
contact.type = 'phone';
contact.value = '';
};
}
</script>
<div id="ctrl-exmpl" ng-controller="SettingsController2">
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>
</file>
<file name="protractor.js" type="protractor">
it('should check controller', function() {
var container = element(by.id('ctrl-exmpl'));
expect(container.findElement(by.model('name'))
.getAttribute('value')).toBe('John Smith');
var firstRepeat =
container.findElement(by.repeater('contact in contacts').row(0));
var secondRepeat =
container.findElement(by.repeater('contact in contacts').row(1));
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('408 555 1212');
expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('john.smith@example.org');
firstRepeat.findElement(by.linkText('clear')).click();
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('');
container.findElement(by.linkText('add')).click();
expect(container.findElement(by.repeater('contact in contacts').row(2))
.findElement(by.model('contact.value'))
.getAttribute('value'))
.toBe('yourname@example.org');
});
</file>
</example>
* Two different declaration styles are included below:
*
* * one binds methods and properties directly onto the controller using `this`:
* `ng-controller="SettingsController1 as settings"`
* * one injects `$scope` into the controller:
* `ng-controller="SettingsController2"`
*
* The second option is more common in the Angular community, and is generally used in boilerplates
* and in this guide. However, there are advantages to binding properties directly to the controller
* and avoiding scope.
*
* * Using `controller as` makes it obvious which controller you are accessing in the template when
* multiple controllers apply to an element.
* * If you are writing your controllers as classes you have easier access to the properties and
* methods, which will appear on the scope, from inside the controller code.
* * Since there is always a `.` in the bindings, you don't have to worry about prototypal
* inheritance masking primitives.
*
* This example demonstrates the `controller as` syntax.
*
* <example name="ngControllerAs">
* <file name="index.html">
* <div id="ctrl-as-exmpl" ng-controller="SettingsController1 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>
* </file>
* <file name="app.js">
* function SettingsController1() {
* this.name = "John Smith";
* this.contacts = [
* {type: 'phone', value: '408 555 1212'},
* {type: 'email', value: 'john.smith@example.org'} ];
* }
*
* SettingsController1.prototype.greet = function() {
* alert(this.name);
* };
*
* SettingsController1.prototype.addContact = function() {
* this.contacts.push({type: 'email', value: 'yourname@example.org'});
* };
*
* SettingsController1.prototype.removeContact = function(contactToRemove) {
* var index = this.contacts.indexOf(contactToRemove);
* this.contacts.splice(index, 1);
* };
*
* SettingsController1.prototype.clearContact = function(contact) {
* contact.type = 'phone';
* contact.value = '';
* };
* </file>
* <file name="protractor.js" type="protractor">
* it('should check controller as', function() {
* var container = element(by.id('ctrl-as-exmpl'));
* expect(container.findElement(by.model('settings.name'))
* .getAttribute('value')).toBe('John Smith');
*
* var firstRepeat =
* container.findElement(by.repeater('contact in settings.contacts').row(0));
* var secondRepeat =
* container.findElement(by.repeater('contact in settings.contacts').row(1));
*
* expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
* .toBe('408 555 1212');
*
* expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
* .toBe('john.smith@example.org');
*
* firstRepeat.findElement(by.linkText('clear')).click();
*
* expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
* .toBe('');
*
* container.findElement(by.linkText('add')).click();
*
* expect(container.findElement(by.repeater('contact in settings.contacts').row(2))
* .findElement(by.model('contact.value'))
* .getAttribute('value'))
* .toBe('yourname@example.org');
* });
* </file>
* </example>
*
* This example demonstrates the "attach to `$scope`" style of controller.
*
* <example name="ngController">
* <file name="index.html">
* <div id="ctrl-exmpl" ng-controller="SettingsController2">
* 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>
* </file>
* <file name="app.js">
* function SettingsController2($scope) {
* $scope.name = "John Smith";
* $scope.contacts = [
* {type:'phone', value:'408 555 1212'},
* {type:'email', value:'john.smith@example.org'} ];
*
* $scope.greet = function() {
* alert($scope.name);
* };
*
* $scope.addContact = function() {
* $scope.contacts.push({type:'email', value:'yourname@example.org'});
* };
*
* $scope.removeContact = function(contactToRemove) {
* var index = $scope.contacts.indexOf(contactToRemove);
* $scope.contacts.splice(index, 1);
* };
*
* $scope.clearContact = function(contact) {
* contact.type = 'phone';
* contact.value = '';
* };
* }
* </file>
* <file name="protractor.js" type="protractor">
* it('should check controller', function() {
* var container = element(by.id('ctrl-exmpl'));
*
* expect(container.findElement(by.model('name'))
* .getAttribute('value')).toBe('John Smith');
*
* var firstRepeat =
* container.findElement(by.repeater('contact in contacts').row(0));
* var secondRepeat =
* container.findElement(by.repeater('contact in contacts').row(1));
*
* expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
* .toBe('408 555 1212');
* expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
* .toBe('john.smith@example.org');
*
* firstRepeat.findElement(by.linkText('clear')).click();
*
* expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
* .toBe('');
*
* container.findElement(by.linkText('add')).click();
*
* expect(container.findElement(by.repeater('contact in contacts').row(2))
* .findElement(by.model('contact.value'))
* .getAttribute('value'))
* .toBe('yourname@example.org');
* });
* </file>
*</example>
*/
var ngControllerDirective = [function() {