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 ou ngHide, 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 como acme-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 diretiva acme- 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, como ion- 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 opcionalmente A (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 de controller 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>
    

De volta ao topo