link
method. // function MainCtrl (SomeService) { this.makeActive = function (elem) { elem.addClass('test'); }; } angular .module('app') .controller('MainCtrl', MainCtrl);
// function SomeDirective (SomeService) { return { restrict: 'EA', template: [ '<a href="" class="myawesomebutton" ng-transclude>', '<i class="icon-ok-sign"></i>', '</a>' ].join(''), link: function ($scope, $element, $attrs) { // DOM manipulation/events here! $element.on('click', function () { $(this).addClass('test'); }); } }; } angular .module('app') .directive('SomeDirective', SomeDirective);
ng-*
in the name, in order to avoid possible reassignment of code by future Angular releases. Surely, at the time of the emergence of ng-focus
, many directives were written, with the same name, whose application work was paralyzed only because of the use of the same name. Also, the use of this prefix is ​​confusing, and apparently from the presentation code it is not clear which of the directives are written by the user, and which ones came with the library. function ngFocus (SomeService) { return {}; } angular .module('app') .directive('ngFocus', ngFocus);
function focusFire (SomeService) { return {}; } angular .module('app') .directive('focusFire', focusFire);
focusFire
directive in a view, we focusFire
it via <input focus-fire>
. <!-- directive: my-directive --> <div class="my-directive"></div>
<my-directive></my-directive> <div my-directive></div>
angular-route.js
(or similar third-party add-ons, such as ui-router.js
), we can use the resolve
property to resolve the promises of the next view until the finished page is displayed to us. This means that the controller for this view will be created immediately after receiving all the data, and this in turn means that up to this point there will be no function calls. function MainCtrl (SomeService) { var self = this; // self.something; // SomeService.doSomething().then(function (response) { self.something = response; }); } angular .module('app') .controller('MainCtrl', MainCtrl);
function config ($routeProvider) { $routeProvider .when('/', { templateUrl: 'views/main.html', resolve: { doSomething: function (SomeService) { return SomeService.doSomething(); } } }); } angular .module('app') .config(config);
function MainCtrl (SomeService) { // ! this.something = SomeService.something; } angular .module('app') .controller('MainCtrl', MainCtrl);
resolve
property directly to the controller code, thus avoiding any logic in the router code. // , resolve function config ($routeProvider) { $routeProvider .when('/', { templateUrl: 'views/main.html', controller: 'MainCtrl', controllerAs: 'main', resolve: MainCtrl.resolve }); } // , function MainCtrl (SomeService) { // ! this.something = SomeService.something; } // resolve MainCtrl.resolve = { doSomething: function (SomeService) { return SomeService.doSomething(); } }; angular .module('app') .controller('MainCtrl', MainCtrl) .config(config);
$routeChangeStart
event when we leave the current page. At this very moment you can show the spinner. And you can remove it at the moment of occurrence of the $routeChangeSuccess
( more details here ).$scope.$watch
only when there is no way to do without it. It is worth remembering that in terms of performance, it is significantly inferior to ng-change
solutions. <input ng-model="myModel"> <script> $scope.$watch('myModel', callback); </script>
<input ng-model="myModel" ng-change="callback"> <!-- $scope.callback = function () { // go }; -->
|-- app.js |-- controllers.js |-- filters.js |-- services.js |-- directives.js
|-- app.js |-- controllers/ | |-- MainCtrl.js | |-- AnotherCtrl.js |-- filters/ | |-- MainFilter.js | |-- AnotherFilter.js |-- services/ | |-- MainService.js | |-- AnotherService.js |-- directives/ | |-- MainDirective.js | |-- AnotherDirective.js
|-- app.js |-- dashboard/ | |-- DashboardService.js | |-- DashboardCtrl.js |-- login/ | |-- LoginService.js | |-- LoginCtrl.js |-- inbox/ | |-- InboxService.js | |-- InboxCtrl.js
$
sign, for example, $scope
or $rootScope
. This symbol as if hints to us that an object is public and can be interacted with from different places. We are also familiar with things like $$listeners
, which are also available in the code, but are considered private.$
and $$
as prefixes in the names of your own directives / services / controllers / providers / factories.$$SomeService
as the definition, while leaving the name of the function without prefixes. function SomeService () { } angular .module('app') .factory('$$SomeService', SomeService);
SomeService
as the definition and name of the function itself for a more expressive stack trace. function SomeService () { } angular .module('app') .factory('SomeService', SomeService);
// function SomeCtrl (MyService, $scope, AnotherService, $rootScope) { }
// Angular -> function SomeCtrl ($scope, $rootScope, MyService, AnotherService) { }
ng-annotate
for automatic annotation of dependencies, because ng-min
outdated and no longer supported . As for ng-annotate
, so more about it here .@ngInject
comment before those functions with dependencies. This comment is a ng-annotate
instruction for automatically describing the dependencies of a module. function SomeService ($scope) { } // – SomeService.$inject = ['$scope']; angular .module('app') .factory('SomeService', SomeService);
/** * @ngInject */ function SomeService ($scope) { } angular .module('app') .factory('SomeService', SomeService);
/** * @ngInject */ function SomeService ($scope) { } // ng-annotate SomeService.$inject = ['$scope']; angular .module('app') .factory('SomeService', SomeService);
Source: https://habr.com/ru/post/237279/
All Articles