/
githubmirror
/
angular.js
Обзор
Документация
Войти
/
githubmirror
/
angular.js
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/ng/directive/ngController.js
234 строки
9 KB
Martin Staffa
fix($controller): remove instantiating controllers defined on window
01 мар 2017, 15:27
01 мар 2017, 15:27
e269c14
Код
Авторство
О чём код?
'use strict'; /** * @ngdoc directive * @name ngController * * @description * 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: * * * Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties * are accessed through bindings. * * View — The template (HTML with data bindings) that is rendered into the View. * * Controller — The `ngController` directive specifies a Controller class; the class contains business * logic behind the application to decorate the scope with functions and values * * Note that you can also attach controllers to the DOM by declaring it in a route definition * via the {@link ngRoute.$route $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. * * @element ANY * @scope * @priority 500 * @param {expression} ngController Name of a constructor function registered with the current * {@link ng.$controllerProvider $controllerProvider} or an {@link guide/expression expression} * that on the current scope evaluates to a constructor function. * * The controller instance can be published into a scope property by specifying * `ng-controller="as propertyName"`. * * @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 AngularJS 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 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 AngularJS 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" module="controllerAsExample"> * <file name="index.html"> * <div id="ctrl-as-exmpl" ng-controller="SettingsController1 as settings"> * <label>Name: <input type="text" ng-model="settings.name"/></label> * <button ng-click="settings.greet()">greet</button><br/> * Contact: * <ul> * <li ng-repeat="contact in settings.contacts"> * <select ng-model="contact.type" aria-label="Contact method" id="select_{{$index}}"> * <option>phone</option> * <option>email</option> * </select> * <input type="text" ng-model="contact.value" aria-labelledby="select_{{$index}}" /> * <button ng-click="settings.clearContact(contact)">clear</button> * <button ng-click="settings.removeContact(contact)" aria-label="Remove">X</button> * </li> * <li><button ng-click="settings.addContact()">add</button></li> * </ul> * </div> * </file> * <file name="app.js"> * angular.module('controllerAsExample', []) * .controller('SettingsController1', SettingsController1); * * 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.element(by.model('settings.name')) * .getAttribute('value')).toBe('John Smith'); * * var firstRepeat = * container.element(by.repeater('contact in settings.contacts').row(0)); * var secondRepeat = * container.element(by.repeater('contact in settings.contacts').row(1)); * * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) * .toBe('408 555 1212'); * * expect(secondRepeat.element(by.model('contact.value')).getAttribute('value')) * .toBe('john.smith@example.org'); * * firstRepeat.element(by.buttonText('clear')).click(); * * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) * .toBe(''); * * container.element(by.buttonText('add')).click(); * * expect(container.element(by.repeater('contact in settings.contacts').row(2)) * .element(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" module="controllerExample"> * <file name="index.html"> * <div id="ctrl-exmpl" ng-controller="SettingsController2"> * <label>Name: <input type="text" ng-model="name"/></label> * <button ng-click="greet()">greet</button><br/> * Contact: * <ul> * <li ng-repeat="contact in contacts"> * <select ng-model="contact.type" id="select_{{$index}}"> * <option>phone</option> * <option>email</option> * </select> * <input type="text" ng-model="contact.value" aria-labelledby="select_{{$index}}" /> * <button ng-click="clearContact(contact)">clear</button> * <button ng-click="removeContact(contact)">X</button> * </li> * <li>[ <button ng-click="addContact()">add</button> ]</li> * </ul> * </div> * </file> * <file name="app.js"> * angular.module('controllerExample', []) * .controller('SettingsController2', ['$scope', SettingsController2]); * * 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.element(by.model('name')) * .getAttribute('value')).toBe('John Smith'); * * var firstRepeat = * container.element(by.repeater('contact in contacts').row(0)); * var secondRepeat = * container.element(by.repeater('contact in contacts').row(1)); * * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) * .toBe('408 555 1212'); * expect(secondRepeat.element(by.model('contact.value')).getAttribute('value')) * .toBe('john.smith@example.org'); * * firstRepeat.element(by.buttonText('clear')).click(); * * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) * .toBe(''); * * container.element(by.buttonText('add')).click(); * * expect(container.element(by.repeater('contact in contacts').row(2)) * .element(by.model('contact.value')) * .getAttribute('value')) * .toBe('yourname@example.org'); * }); * </file> *</example> */ var ngControllerDirective = [function() { return { restrict: 'A', scope: true, controller: '@', priority: 500 }; }];