Directives
ou Diretivas
Limit 1 Per File
ou Limite 1 por arquivo
Crie uma diretiva (directive) por arquivo. Nomeie o arquivo pela diretiva.
Por que? É fácil misturar todas as diretivas em um arquivo, mas é difícil depois separá-las, já que algumas são compartilhadas entre aplicativos, outras pelos módulos (modules) e algumas somente para um módulo.
Por que? Uma diretiva (directive) por arquivo é mais fácil de dar manutenção.
```javascript / evite / / directives.js /
angular .module('app.widgets')
/ diretiva de pedido (order) que é específica para o módulo de pedido / .directive('orderCalendarRange', orderCalendarRange)
/ diretiva de vendas (sales) que pode ser usada em qualquer lugar do aplicativo de vendas / .directive('salesCustomerInfo', salesCustomerInfo)
/ diretiva de spinner que pode ser usada em qualquer lugar dos aplicativos / .directive('sharedSpinner', sharedSpinner);
function orderCalendarRange() {
/* detalhes de implementação */
}
function salesCustomerInfo() {
/* detalhes de implementação */
}
function sharedSpinner() {
/* detalhes de implementação */
}
```javascript
/* recomendado */
/* calendarRange.directive.js */
/**
* @desc diretiva de pedido (order) que é específica para o módulo de pedido em uma companhia chamada Acme
* @example <div acme-order-calendar-range></div>
*/
angular
.module('sales.order')
.directive('acmeOrderCalendarRange', orderCalendarRange);
function orderCalendarRange() {
/* detalhes de implementação */
}
/* recomendado */
/* customerInfo.directive.js */
/**
* @desc diretiva de spinner que pode ser usada em qualquer lugar de um aplicativo de vendas em uma companhia chamada Acme
* @example <div acme-sales-customer-info></div>
*/
angular
.module('sales.widgets')
.directive('acmeSalesCustomerInfo', salesCustomerInfo);
function salesCustomerInfo() {
/* detalhes de implementação */
}
/* recomendado */
/* spinner.directive.js */
/**
* @desc diretiva de spinner que pode ser usada em qualquer lugar de aplicativo em uma companhia chamada Acme
* @example <div acme-shared-spinner></div>
*/
angular
.module('shared.widgets')
.directive('acmeSharedSpinner', sharedSpinner);
function sharedSpinner() {
/* detalhes de implementação */
}
Nota: Há diferentes opções de nomear diretivas (directives), especialmente quando elas podem ser usadas em escopos (scopes) variados. Escolha uma que faça a diretiva e o nome do arquivo distinto e simples. Alguns exemplos são mostrados abaixo, mas veja a seção de nomeação para mais recomendações.
Limit DOM Manipulation
ou Limite a manipulação do DOM
Quando estiver manipulando o DOM diretamente, utilize uma diretiva (directive). Se formas alternativas podem ser utilizadas, como: utilizar CSS para setar estilos ou serviços de animação (animation services), Angular templating,
ngShow
oungHide
, então prefira utilizá-los. Por exemplo, se uma diretiva simplesmente esconde ou mostra um elemento, use ngHide/ngShow.Por que? A manipulação do DOM pode ser difícil de testar, debugar, e há melhores maneiras (ex: CSS, animações (animations), templates).
Provide a Unique Directive Prefix
ou Forneça um prefixo único para as diretivas
Forneça um curto, único e descritivo prefixo para a diretiva, como
acmeSalesCustomerInfo
, que é declarado no HTML comoacme-sales-customer-info
.Por que? Um prefixo curto e único identifica o contexto e a origem da diretiva. Por exemplo, o prefixo
cc-
pode indicar que a diretiva é parte de um aplicativo da CodeCamper, enquanto a diretivaacme-
pode indicar uma diretiva para a companhia Acme.Nota: Evite
ng-
, pois são reservadas para as diretivas do AngularJS. Pesquise largamente as diretivas utilizadas para evitar conflitos de nomes, comoion-
que são utilizadas para o Ionic Framework.
Restrict to Elements and Attributes
ou Restringir para elementos e atributos
Quando criar uma diretiva que faça sentido por si só como um elemento, utilize restrição
E
(elemento personalizado) e opcionalmenteA
(atributo personalizado). Geralmente, se ela pode ter o seu próprio controlador (controller),E
é o apropriado. Em linhas gerais,EA
é permitido, mas atente para a implementação como elemento quando faz sentido por si só e como atributo quando estende algo existente no DOM.Por que? Faz sentido.
Por que? Nós podemos utilizar uma diretiva como uma classe (class), mas se a diretiva está realmente agindo como um elemento, faz mais sentido utilizar como um elemento, ou pelo menos como um atributo.
Nota: EA é o padrão para o Angular 1.3 +
<!-- evite --> <div class="my-calendar-range"></div>
/* evite */ angular .module('app.widgets') .directive('myCalendarRange', myCalendarRange); function myCalendarRange() { var directive = { link: link, templateUrl: '/template/is/located/here.html', restrict: 'C' }; return directive; function link(scope, element, attrs) { /* */ } }
<!-- recomendado --> <my-calendar-range></my-calendar-range> <div my-calendar-range></div>
/* recomendado */ angular .module('app.widgets') .directive('myCalendarRange', myCalendarRange); function myCalendarRange() { var directive = { link: link, templateUrl: '/template/is/located/here.html', restrict: 'EA' }; return directive; function link(scope, element, attrs) { /* */ } }
Directives and ControllerAs
ou Diretivas e "ControladorComo"
Utilize a sintaxe
controller as
com uma diretiva para consistência com o uso decontroller as
com os pares view e controlador (controller).Por que? Faz sentido e não é difícil.
Nota: A diretiva (directive) abaixo demonstra algumas maneiras que você pode utilizar escopos (scopes) dentro de link e controller de uma diretiva, utilizando controllerAs. Eu coloquei o template somente para manter tudo em um mesmo local.
<div my-example max="77"></div>
angular .module('app') .directive('myExample', myExample); function myExample() { var directive = { restrict: 'EA', templateUrl: 'app/feature/example.directive.html', scope: { max: '=' }, link: linkFunc, controller : ExampleController, controllerAs: 'vm' }; return directive; ExampleController.$inject = ['$scope']; function ExampleController($scope) { // Injetando $scope somente para comparação /* jshint validthis:true */ var vm = this; vm.min = 3; vm.max = $scope.max; console.log('CTRL: $scope.max = %i', $scope.max); console.log('CTRL: vm.min = %i', vm.min); console.log('CTRL: vm.max = %i', vm.max); } function linkFunc(scope, el, attr, ctrl) { console.log('LINK: scope.max = %i', scope.max); console.log('LINK: scope.vm.min = %i', scope.vm.min); console.log('LINK: scope.vm.max = %i', scope.vm.max); } }
<!-- example.directive.html --> <div>hello world</div> <div>max=<input ng-model="vm.max"/></div> <div>min=<input ng-model="vm.min"/></div>