The ngController
directive attaches a controller class to the view. This is a key aspect of how angular
supports the principles behind the Model-View-Controller design pattern.
MVC components in angular:
ngController
directive specifies a Controller class; the class contains business
logic behind the application to decorate the scope with functions and valuesNote that you can also attach controllers to the DOM by declaring it in a route definition
via the $route service. A common mistake is to declare the controller
again using ng-controller
in the template itself. This will cause the controller to be attached
and executed twice.
<ANY
ng-controller="">
...
</ANY>
Param | Type | Details |
---|---|---|
ngController | expression |
Name of a globally accessible constructor function or an
expression that on the current scope evaluates to a
constructor function. The controller instance can be published into a scope property
by specifying |
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 shown in two different declaration styles you may use
according to preference.
<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>
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');
});
<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(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 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>
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');
});