Diretivas AngularJS: isolate scope

Diretivas nos permitem estender o HTML e criar nossos próprios elementos. Podemos definir como esses elementos vão se comportar em cada caso usando atributos, bem parecido com os Custom Elements. Neste post vamos entender o que é isolate scope e como ele funciona.

Scope

No objeto de definição de uma diretiva, temos a propriedade scope que pode se comportar de três formas de acordo com o seu valor:

false|default: sem scope

Por padrão as diretivas não criam um escopo, ou seja, ela utiliza exatamente o mesmo escopo de onde ela for inserida, podendo modificar seus valores.

true: novo scope

Quando definido como true é definido um novo scope, que herda (henraça prototipal) do scope pai.

{ foo: '=', bar: '@', baz: '&' }: isolate scope

O escopo isolado nos permite definir uma API via atributos HTML além de não herdar do escopo pai. Nossos atributos podem receber três valores diferentes que correspondem a como eles irão se comportar:

= two-way data-binding

@ top-down binding

& executar um método no escopo do pai

Não entendeu nada? Não tem problema, vamos ver um exemplo para ajudar.


Criando uma diretiva reutilizável usando isolate scope

Para entender como o isolate scope funciona na pratica, vamos construir uma diretiva que encapsula o funcionamento do componente alert do Bootstrap.

Você pode ver o resultado final aqui: http://plnkr.co/edit/vVVO74OxvmGumVdPkUxh?p=preview

API

Repare como usando atributos HTML nós definimos o tipo de alerta e como vamos fechá-la.

<my-alert type=”type” close=”close()” ng-hide=”closed”>
<strong>Warning!</strong> Better check yourself.
</my-alert>

Definindo a diretiva

O que queremos fazer é habilitar o two-way data-binding para o model type e executar o método close que for passado para o nosso componente de alerta:

app.directive(‘myAlert’, function() {
return {
restrict: ‘EA’, // elemento ou atributo
transclude: true,
templateUrl: ‘alert.html’,
scope: {
type: ‘=’, // two-way data-binding
close: ‘&’ // executa um método no escopo pai
}
};
});

Nós também poderíamos usar o valor ‘@’ para o atributo type. A diferença é que ao invés de esperar o nome do model para habilitar o data-binding, a nossa diretiva passaria a esperar por uma expressão Angular.

<my-alert type=”{{ type }}” close=”close()” ng-hide=”closed”>
<strong>Warning!</strong> Better check yourself...
</my-alert>

A diferença entre ‘@’ e ‘=’ é que usando expressões temos mais controle sobre os valores que são passados para o atributo em questão. Veja um exemplo:

<my-alert type=”{{ type || 'info' }}”>
<strong>Warning!</strong> Better check yourself...
</my-alert>

Conclusão

Entender como o isolate scope funciona é essencial para criar componentes altamente reutilizáveis, flexíveis, customizáveis e auto-contidos. É um grande passo em direção ao domínio do uso das diretivas do AngularJS.