Que ótima pergunta! Eu amo ouvir o que os outros têm a dizer, mas aqui estão as diretrizes que eu uso.
A premissa de alta altitude: escopo é usada como a "cola" que usamos para nos comunicar entre o controlador pai, a diretiva e o modelo de diretiva.
Escopo pai:, scope: false
portanto, nenhum novo escopo
Eu não uso isso com muita frequência, mas como o @MarkRajcok disse, se a diretiva não acessa nenhuma variável de escopo (e obviamente não define nenhuma!), Então isso é bom para mim. Isso também é útil para diretivas filho que são usadas apenas no contexto da diretiva pai (embora sempre haja exceções a isso) e que não tenham um modelo. Basicamente, qualquer coisa com um modelo não pertence ao compartilhamento de um escopo, porque você está expondo inerentemente esse escopo para acesso e manipulação (mas tenho certeza de que há exceções a essa regra).
Como exemplo, criei recentemente uma diretiva que desenha um gráfico vetorial (estático) usando uma biblioteca SVG que estou escrevendo. Ele possui $observe
dois atributos ( width
e height
) e os utiliza em seus cálculos, mas não define nem lê nenhuma variável de escopo e não possui modelo. Este é um bom caso de uso para não criar outro escopo; nós não precisamos de um, então por que se preocupar?
Porém, em outra diretiva SVG, eu exigi um conjunto de dados para usar e, adicionalmente, tive que armazenar um pouquinho de estado. Nesse caso, o uso do escopo pai seria irresponsável (novamente, de um modo geral). Então, ao invés ...
Escopo da criança: scope: true
As diretivas com um escopo filho são sensíveis ao contexto e se destinam a interagir com o escopo atual.
Obviamente, uma vantagem importante disso em relação a um escopo isolado é que o usuário é livre para usar a interpolação em qualquer atributo que desejar; por exemplo, usar class="item-type-{{item.type}}"
uma diretiva com um escopo isolado não funcionará por padrão, mas funciona bem em uma com um escopo filho, porque o que for interpolado ainda pode, por padrão, ser encontrado no escopo pai. Além disso, a própria diretiva pode avaliar com segurança atributos e expressões no contexto de seu próprio escopo sem se preocupar com poluição ou danos aos pais.
Por exemplo, uma dica de ferramenta é algo que apenas é adicionado; um escopo isolado não funcionaria (por padrão, veja abaixo) porque é esperado que usemos outras diretivas ou atributos interpolados aqui. A dica de ferramenta é apenas um aprimoramento. Mas a dica de ferramenta também precisa definir algumas coisas no escopo para usar com uma sub-diretiva e / ou modelo e, obviamente, gerenciar seu próprio estado, portanto seria muito ruim usar o escopo pai. Nós estamos poluindo ou danificando, e nem é bueno.
Eu me pego usando escopos filhos com mais frequência do que isolados ou escopos parentais.
Isolar o escopo: scope: {}
Isto é para componentes reutilizáveis. :-)
Mas, falando sério, penso em "componentes reutilizáveis" como "componentes independentes". A intenção é que eles sejam usados para uma finalidade específica, portanto, combiná-los com outras diretivas ou adicionar outros atributos interpolados ao nó DOM inerentemente não faz sentido.
Para ser mais específico, tudo o que é necessário para essa funcionalidade autônoma é fornecido por meio de atributos especificados avaliados no contexto do escopo pai; elas são cadeias de mão única ('@'), expressões de mão única ('&') ou ligações de variável de mão dupla ('=').
Em componentes independentes, não faz sentido precisar aplicar outras diretivas ou atributos nele, porque ele existe por si só. Seu estilo é regido por seu próprio modelo (se necessário) e pode ter o conteúdo apropriado transcluído (se necessário). É autônomo, portanto, colocamos em um escopo isolado também para dizer: "Não mexa com isso. Estou fornecendo uma API definida por esses poucos atributos".
Uma boa prática é excluir o máximo possível de itens baseados em modelos das funções de link e controlador de diretiva. Isso fornece outro ponto de configuração "semelhante à API": o usuário da diretiva pode simplesmente substituir o modelo! A funcionalidade permaneceu a mesma e sua API interna nunca foi tocada, mas podemos mexer com o estilo e a implementação do DOM o quanto for necessário. ui / bootstrap é um ótimo exemplo de como fazer isso bem, porque Peter e Pawel são incríveis.
Os escopos de isolamento também são ótimos para uso com transclusão. Tome guias; eles não são apenas toda a funcionalidade, mas tudo o que está dentro dela pode ser avaliado livremente no escopo pai, deixando as guias (e os painéis) para fazer o que quiserem. As guias claramente têm seu próprio estado , que pertence ao escopo (para interagir com o modelo), mas esse estado não tem nada a ver com o contexto em que foi usado - é inteiramente interno ao que faz de uma diretiva de guia uma diretiva de guia. Além disso, não faz muito sentido usar outras diretivas com as guias. São guias - e já temos essa funcionalidade!
Envolva-o com mais funcionalidade ou transclua mais funcionalidade, mas a diretiva é o que já é.
Dito isso, devo observar que existem maneiras de contornar algumas das limitações (ou seja, recursos) de um escopo isolado, como o @ProLoser sugeriu em sua resposta. Por exemplo, na seção escopo filho, mencionei a interpolação em atributos não-diretivos que quebram ao usar um escopo isolado (por padrão). Mas o usuário poderia, por exemplo, simplesmente usar class="item-type-{{$parent.item.type}}"
e funcionaria mais uma vez. Portanto, se houver um motivo convincente para usar um escopo isolado em relação a um escopo filho, mas você estiver preocupado com algumas dessas limitações, saiba que pode contornar praticamente todas elas, se necessário.
Resumo
Diretivas sem novo escopo são somente leitura; eles são totalmente confiáveis (ou seja, internos ao aplicativo) e não tocam no conector. Diretivas com escopo filho adicionam funcionalidade, mas elas não são a única funcionalidade. Por fim, os escopos isolados são para diretivas que são o objetivo inteiro; eles são independentes, então não há problema (e é mais "correto") deixá-los desonestos.
Eu queria expressar meus pensamentos iniciais, mas, ao pensar em mais coisas, atualizo isso. Mas caramba - isso é tempo para uma resposta SO ...
PS: Totalmente tangencial, mas como estamos falando de escopos, prefiro dizer "prototípico", enquanto outros preferem "prototípico", o que parece ser mais preciso, mas não sai nada bem da língua. :-)