Aplicações Híbridas para Dispositivos Móveis com AngularJS e PhoneGap
AngularJS - 10 passos para aprender a criar suas directivas
-
Upload
janderson-cardoso -
Category
Software
-
view
1.392 -
download
1
Transcript of AngularJS - 10 passos para aprender a criar suas directivas
AngularJS Directives10 passos para aprender a criar sua directivas
Os 10 Passos são:• 1 - Uma possível directiva?
• 2 - Criando uma directiva com template inline.
• 3 - Directiva com template externo e usando o restrict mode.
• 4 - Criando um módulo para a directiva.
• 5 - Outra view usando a mesma directiva.
• 6 - Isolando o escopo da directiva.
• 7 - Utilizando o Transclude.
• 8 - Adicionando ações a directiva.
• 9 - Criando uma controladora para a directiva.
• 10 - Complicando a vida e criando directivas com dependência de outras directivas.
@jandersonfc
Angular-seed
https://github.com/angular/angular-seed
@jandersonfc
1 - Uma possível directiva?View01.js
View01.html
@jandersonfc
2 - Criando uma directiva com template
inlineView02.js
View02.html
@jandersonfc
<div card-profile></div>
Por padrão as directivas serão usadas como atributo
View01.html
@jandersonfc
2 - Criando uma directiva com template
inline
<div ng-repeat="user in users">
<div card-profile></div>
</div>
Por padrão as directivas compartilham do mesmo escopo do
parent. No nosso caso o scope da View02Ctrl.
.directive('cardProfile', [function(){
return {
template: '<h2>{{user.name}}</h2>\n'+
'<p>Twitter: {{user.twitter}}</p>\n'+
'<p>website: <a href="{{user.website}}">{{user.website}}</a></p>'
};
}])
View02.html
View02.js
@jandersonfc
2 - Criando uma directiva com template
inline
3 - Directiva com template externo e
usando o restrict mode
View03.js
View03.html
card-profile.html
@jandersonfc
.directive('cardProfile2', [function(){
return {
restrict: 'E',
templateUrl: 'view03/card-profile.html'
};
}])
restrict indica como a directiva pode ser usada.
View03.js
<div ng-repeat="user in users">
<card-profile2></card-profile2>
</div>
View03.html
Caso o valor do restrict seja ‘E’ a directiva só pode ser usada como Element.
@jandersonfc
3 - Directiva com template externo e
usando o restrict mode
.directive('cardProfile2', [function(){
return {
restrict: 'A',
templateUrl: 'view03/card-profile.html'
};
}])
restrict indica como a directiva pode ser usada.
View03.js
<div ng-repeat="user in users">
<div card-profile2></div>
</div>
View03.html
Caso o valor do restrict seja ‘A’ a directiva só pode ser usada como Attribute.
@jandersonfc
3 - Directiva com template externo e
usando o restrict mode
.directive('cardProfile2', [function(){
return {
restrict: 'C',
templateUrl: 'view03/card-profile.html'
};
}])
restrict indica como a directiva pode ser usada.
View03.js
<div ng-repeat="user in users">
<div class="card-profile2"></div>
</div>
View03.html
Caso o valor do restrict seja ‘C’ a directiva só pode ser usada como Class.
@jandersonfc
3 - Directiva com template externo e
usando o restrict mode
.directive('cardProfile2', [function(){
return {
restrict: 'M',
templateUrl: 'view03/card-profile.html'
};
}])
restrict indica como a directiva pode ser usada.
View03.js
<div ng-repeat="user in users">
<!-- directive: card-profile2 -->
</div>
View03.html
Caso o valor do restrict seja ‘M’ a directiva só pode ser usada como Comment.
@jandersonfc
3 - Directiva com template externo e
usando o restrict mode
.directive('cardProfile2', [function(){
return {
restrict: 'EACM',
templateUrl: 'view03/card-profile.html'
};
}])
restrict indica como a directiva pode ser usada.
View03.js
Uma directiva pode ter mais de um restrict mode
@jandersonfc
3 - Directiva com template externo e
usando o restrict mode
.directive('cardProfile2', [function(){
return {
restrict: 'M',
templateUrl: 'view03/card-profile.html'
};
}])
templateUrl é usado para indicar o arquivo que essa
directiva irá usar como template.
View03.js
<h2>{{user.name}}</h2>
<p>Twitter: {{user.twitter}}</p>
<p>website: <a href="{{user.website}}">{{user.website}}</a></p>
card-profile.html
@jandersonfc
3 - Directiva com template externo e
usando o restrict mode
Dicas e Truques• Evite usar template externo desnecessário. O angular para usar esse template
externo faz uma chamada http (GET). Isso é bem mais lento que deixar o template
inline.
• Template externo é bem mais legível, eu sei. Uma possibilidade é usar o
templateCache. Assim você evitará múltiplas chamadas http desnecessários. Para
saber mais sobre templateCache acesse
https://docs.angularjs.org/api/ng/service/$templateCache .
• Não existe uma regra para usar o restrict mode, é comum achar uma directiva com
acesso 'use e abuse' (restrict: ‘EAC’).
• É recomendável usar o restrict como Atributo ( restrict: 'A' ) quando sua directiva
adicionar ou mudar o comportamento de um componente existente. (ex. <input
validar-cpf />).
• Quando sua directiva é um novo componente que adicionará novos elementos e
comportamentos, recomenda-se usar Element ( restrict: ‘E' ). (ex. <card-profile /> ).
@jandersonfc
3 - Directiva com template externo e
usando o restrict mode
4 - Criando um módulo para a directiva
jfc-card-profile.js
View04.html
card-profile04.html
@jandersonfc
'use strict';
// Declare app level module which
depends on views, and components
angular.module('myApp', [
'ngRoute',
'myApp.view01',
'myApp.view02',
'myApp.view03',
'myApp.view04',
'myApp.view05',
'myApp.view06',
'myApp.view07',
'myApp.view08',
'myApp.view09',
'myApp.view10',
'myApp.version',
'jfc'
])
Basta adicionar o módulo para ter acesso as directivas.
app.js
<!-- In production use:
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/x.x.x/angular.min.js"></script>
-->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="app.js"></script>
<script src="view01/view01.js"></script>
<script src="view02/view02.js"></script>
<script src="view03/view03.js"></script>
<script src="view04/view04.js"></script>
<script src="view05/view05.js"></script>
<script src="view06/view06.js"></script>
<script src="view07/view07.js"></script>
<script src="view08/view08.js"></script>
<script src="view09/view09.js"></script>
<script src="view10/view10.js"></script>
<script src="components/jfc-card-profile/jfc-card-profile.js"></script>
<script src="components/version/version.js"></script>
<script src="components/version/version-directive.js"></script>
<script src="components/version/interpolate-filter.js"></script>
index.html
@jandersonfc
4 - Criando um módulo para a directiva
<p>This is the partial for view 4.</p>
<p>criando um module para a directive para ser usado e N modules</p>
<jfc-card-profile04></jfc-card-profile04>
View04.html
card-profile04.html.html
<div ng-repeat="user in users">
<h2>{{user.name}}</h2>
<p>Twitter: {{user.twitter}}</p>
<p>website: <a href="{{user.website}}">{{user.website}}</a></p>
</div>
@jandersonfc
Basta adicionar o módulo para ter acesso as directivas.
4 - Criando um módulo para a directiva
Dicas e Truques
• O Angular espera que o nome de sua directiva seja único.
Caso você tenha duas directivas com o mesmo nome,
mesmo sendo de módulos distintos, será lançado um erro.
• É recomendável usar um identificador inicial em suas
directivas (de 2 ou 3 caracteres) para evitar conflitos com
outras directivas. (ex. jfcCardProfile ou brCardProfile no
lugar de cardProfile).
• Não é recomendável usar o identificador inicial ng , esse
é o identificador usado nas directivas do próprio Angular.
@jandersonfc
4 - Criando um módulo para a directiva
5 - Outra view usando a mesma directiva
jfc-card-profile.js
View05.html
card-profile04.html
@jandersonfc
6 - Isolando o escopo da directiva
jfc-card-profile.js
View06.html
card-profile04.html
@jandersonfc
.directive('jfcCardProfile06', [function(){
return {
restrict: 'E',
replace: true,
templateUrl: 'components/jfc-card-profile/jfc-card-profile04.html',
scope: {
users: '=datas'
}
};
}])
scope: {} indica que essa directiva terá seu próprio escopo. A directiva
não terá mais acesso ao escopo do parent. Nossa directiva só terá acesso
as variáveis de escopo informados em sua definição.
<p>This is the partial for view 6.</p>
<p>Isolando o Scope da Directive</p>
<button ng-click="updateUsers()">Update Users</button>
<jfc-card-profile06 datas="users"></jfc-card-profile06>
View06.html
jfc-card-profile.js
@jandersonfc
6 - Isolando o escopo da directiva
.directive('jfcCardProfile06', [function(){
return {
restrict: 'E',
replace: true,
templateUrl: 'components/jfc-card-profile/jfc-card-profile04.html',
scope: {
users: '='
}
};
}])
Se o nome do atributo preenchido no template for igual a variável de
escopo que criamos em nossa directiva, podemos usar apenas o símbolo
‘='.
<p>This is the partial for view 6.</p>
<p>Isolando o Scope da Directive</p>
<button ng-click="updateUsers()">Update Users</button>
<jfc-card-profile06 users="users"></jfc-card-profile06>
View06.html
jfc-card-profile.js
@jandersonfc
6 - Isolando o escopo da directiva
.directive('jfcCardProfile06', [function(){
return {
restrict: 'E',
replace: true,
templateUrl: 'components/jfc-card-profile/jfc-card-profile04.html',
scope: {
users: '='
}
};
}])
O valor '=' indica para a directiva um bi-direcional binding com o escopo
do parent, ou seja, mudando o valor dessa variável na directiva mudará
também no escopo externo(parent) e vice versa.
jfc-card-profile.js
@jandersonfc
6 - Isolando o escopo da directiva
.directive('jfcCardProfile06', [function(){
return {
restrict: 'E',
replace: true,
templateUrl: 'components/jfc-card-profile/jfc-card-profile04.html',
scope: {
users: '='
}
};
}])
replace: true Vai substituir o elemento raiz da declaração da directiva e
vai usar apenas os elementos da directiva.
jfc-card-profile.js
@jandersonfc
6 - Isolando o escopo da directiva
replace: false
replace: true
<jfc-card-profile06 datas="users" class="ng-scope ng-isolate-scope”>
<!-- ngRepeat: user in users —>
<div ng-repeat="user in users" class="ng-scope">
<h2 class="ng-binding">Janderson Fernandes Cardoso</h2>
<p class="ng-binding">Twitter: @jandersonfc</p>
<p>website: <a href="http://jandersonfc.com" class="ng-binding">http://jandersonfc.com</a></p>
</div><!-- end ngRepeat: user in users —>
<div ng-repeat="user in users" class="ng-scope">
<h2 class="ng-binding">Janderson Futebol Clube</h2>
<p class="ng-binding">Twitter: @jandersonfclube</p>
<p>website: <a href="http://jandersonfclube.com" class="ng-binding">http://jandersonfclube.com</a></p>
</div><!-- end ngRepeat: user in users —>
</jfc-card-profile06>
<!-- ngRepeat: user in users —>
<div ng-repeat="user in users" class="ng-scope">
<h2 class="ng-binding">Janderson Fernandes Cardoso</h2>
<p class="ng-binding">Twitter: @jandersonfc</p>
<p>website: <a href="http://jandersonfc.com" class="ng-binding">http://jandersonfc.com</a></p>
</div><!-- end ngRepeat: user in users —>
<div ng-repeat="user in users" class="ng-scope">
<h2 class="ng-binding">Janderson Futebol Clube</h2>
<p class="ng-binding">Twitter: @jandersonfclube</p>
<p>website: <a href="http://jandersonfclube.com" class="ng-binding">http://jandersonfclube.com</a></p>
</div><!-- end ngRepeat: user in users —>
@jandersonfc
6 - Isolando o escopo da directiva
Por que separar o nosso escopo?
• Em nosso exemplo, era obrigatório ter uma variável
chamada users no escopo do parent para a directiva
funcionar. Separando o escopo e passando a informação
por atributo resolvemos esse problema.
• Isolar o escopo da directiva é o primeiro passo para criar
directivas com reuso.
• Separando o escopo garantimos que a directiva só tenha
acesso as informações cruciais para seu funcionamento,
sem correr o risco de alterar algo no escopo do parent
acidentalmente.
@jandersonfc
6 - Isolando o escopo da directiva
7 - Utilizando o Transcludejfc-card-profile.js
View07.html
card-profile07.html
@jandersonfc
<jfc-card-profile07 data="user">
<p>linkedin: <a href="{{user.linkedin}}">{{user.linkedin}}</a></p>
<p>facebook: <a href="{{user.facebook}}">{{user.facebook}}</a></p>
</jfc-card-profile07>
transclude: true indica que a directiva irá extrair os elementos
adicionados como "filhos" na declaração da directiva. Transclude é mais
que isso, mas para facilitar a compreensão desses exemplos vamos no
reter a essa explicação.
View07.html
.directive('jfcCardProfile07', [function(){
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/jfc-card-profile/jfc-card-profile07.html',
scope: {
user: '=data'
}
};
}])
jfc-card-profile.js
@jandersonfc
7 - Utilizando o Transclude
<div>
<h2>{{user.name}}</h2>
<p>Twitter: {{user.twitter}}</p>
<div ng-transclude></div>
<p>website: <a href="{{user.website}}">{{user.website}}</a></p>
</div>
ng-transclude indica exatamente a posição onde os elementos que foram
extraídos serão adicionados.
jfc-card-profile07.html
@jandersonfc
7 - Utilizando o Transclude
8 - Adicionando ações a directivajfc-card-profile.js
card-profile08.html
@jandersonfc
view8.js
view08.html
@jandersonfc
8 - Adicionando ações a directiva
link: function(scope, element, attrs) {
scope.edit = function(user){
user.editMode = true;
}
scope.save = function(user){
user.editMode = false;
scope.onSave({user: user});
}
}
É na função link que criaremos nossas variáveis, funções e manipulação de DOM necessários para fazer nossa directiva funcionar.
jfc-card-profile.js
<div ng-repeat="user in users">
<p>
<h2 ng-hide="user.editMode">{{user.name}}</h2>
<input ng-show="user.editMode" ng-model="user.name"/>
</p>
<p>
<span ng-hide="user.editMode">Twitter: {{user.twitter}}</span>
<input ng-show="user.editMode" ng-model="user.twitter"/>
</p>
<p>
<span ng-hide="user.editMode">website: <a
href="{{user.website}}">{{user.website}}</a></span>
<input ng-show="user.editMode" ng-model="user.website"/>
</p>
<button ng-hide="user.editMode" ng-
click="edit(user)">Edit</button>
<button ng-show="user.editMode" ng-
click="save(user)">Save</button>
</div>
jfc-card-profile08.html
@jandersonfc
8 - Adicionando ações a directiva
link: function(scope, element, attrs) {
• scope - Equivalente ao $scope das controladoras, objeto que
contém nossas variáveis e funções acessíveis ao template.
• element - Representa o jqlite-wrapped do elemento html da nossa
directiva, não é necessário usar o $ do jQuery para manipular
esse elemento, o angular já traz ele pronto para isso. É muito
comum manipular esse elemento quando a directiva é uma forma
de usar um plugin jQuery, ou quando queremos adicionar event
listeners nesse elemento. (ex. element.datepicker(),
element.on('mousedown', function(event) )
• attrs - traz a lista de atributos e seus valores adicionados na
nossa directiva. (ex. <input my-directive min="23" max=“24” />)
@jandersonfc
8 - Adicionando ações a directiva
Escopo com ‘&’ indica uma expressão, no nosso caso passamos uma
função que servirá de callback, veja abaixo:
.directive('jfcCardProfile08', [function(){
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/jfc-card-profile/jfc-
card-profile08.html',
scope: {
users: '=datas',
onSave: '&'
},
link: function(scope, element, attrs) {
scope.edit = function(user){
user.editMode = true;
}
scope.save = function(user){
user.editMode = false;
scope.onSave({user: user});
}
}
};
}])
jfc-card-profile.js<jfc-card-profile08 datas="users" on-save=“saveUser(user)">
</jfc-card-profile08>
view08.html
view08.js.controller('View08Ctrl', ['$scope', function($scope) {
$scope.users = [
{
name: 'Janderson Fernandes Cardoso',
twitter: '@jandersonfc',
website: 'http://jandersonfc.com'
},
{
name: 'Janderson Futebol Clube',
twitter: '@jandersonfclube',
website: 'http://jandersonfclube.com'
}
];
$scope.saveUser = function (user){
console.log('call resource for example');
console.log(user);
}
}]);
@jandersonfc
8 - Adicionando ações a directiva
• Existe a função compile na directiva. na execução do
compile existe a chamada para as funções preLink e
postLink.
• A função link é equivalente ao postLink do compile.
• Ao usar o compile não utilizar a função link.
• Não é recomendável usar a função compile, somente
em caso de performance onde será necessário
executar alguma rotina antes do postLink.
Dicas e Truques
@jandersonfc
8 - Adicionando ações a directiva
9 - Criando uma controladora para a
directiva
jfc-card-profile.js
@jandersonfc
controller: function($scope) {
$scope.setEditModeToFalse = function(){
for (var i = 0; i < $scope.users.length; i++) {
$scope.users[i].editMode = false;
};
}
$scope.edit = function(user){
user.editMode = true;
}
$scope.save = function(user){
user.editMode = false;
$scope.onSave({user: user});
}
},
link: function(scope, element, attrs) {
scope.setEditModeToFalse();
}
Quando criamos uma controller , ela é instanciada antes da execução da
funçao preLink em compile.
jfc-card-profile.js
@jandersonfc
9 - Criando uma controladora para a
directiva
• Usar Controladora parece ser uma ótima forma de
organizar o código da directiva, deixando a lógica de
manipulação de scope na controller e manipulação de
DOM na função link .
• Na documentação do Angular só é recomendado usar
controladora quando você quer expor a API de sua directiva
para outras directivas (veremos como isso funciona no
exemplo 10).
• Portanto, no exemplo 09, não é recomendável usar a
função controller, nesse caso é melhor fazer diretamente
na função link como no exemplo 08.
Dicas e Truques
@jandersonfc
9 - Criando uma controladora para a
directiva
10 - Complicando a vida e criando directivas
com dependência de outras directivas
jfc-card-profile.js
view10.html
jfc-card-profile10-list.html
@jandersonfc
jfc-card-profile.js
jfc-card-profile10-renderer.html
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
jfc-card-profile.js
jfc-card-profile10-view.html
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
jfc-card-profile.js
jfc-card-profile10-edit.html
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
Podemos criar directivas que possuem outras directivas
<jfc-card-profile10-renderer ng-repeat="user in
users"
ng-switch on="user.mode">
</jfc-card-profile10-renderer>
jfc-card-profile10-list.html
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
A controladora pode ser declarada diretamente na directivas como fizemos no
exemplo 09 ou referenciar uma controller existente no módulo.
.controller('cardProfileController', ['$scope', '$attrs', function($scope, $attrs){
this.setModeDefault = function(){
$scope.user.mode = 'view';
}
this.edit = function(){
$scope.user.mode = 'edit';
}
this.save = function(){
$scope.user.mode = 'view';
$scope.onSave({user: $scope.user});
}
}])
.directive('jfcCardProfile10Renderer', function(){
return {
restrict: 'E',
replace: false,
controller: 'cardProfileController',
templateUrl: 'components/jfc-card-profile/jfc-card-profile10-renderer.html',
link: function(scope, element, attrs, ctrl) {
ctrl.setModeDefault();
}
};
})
jfc-card-profile.js
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
A controladora da directiva pode ser acessada através do quarto parâmetro na
declaração da função link.
.controller('cardProfileController', ['$scope', '$attrs', function($scope, $attrs){
this.setModeDefault = function(){
$scope.user.mode = 'view';
}
this.edit = function(){
$scope.user.mode = 'edit';
}
this.save = function(){
$scope.user.mode = 'view';
$scope.onSave({user: $scope.user});
}
}])
.directive('jfcCardProfile10Renderer', function(){
return {
restrict: 'E',
replace: false,
controller: 'cardProfileController',
templateUrl: 'components/jfc-card-profile/jfc-card-profile10-renderer.html',
link: function(scope, element, attrs, ctrl) {
ctrl.setModeDefault();
}
};
})
jfc-card-profile.js
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
ng-switch é uma diretiva do angular que você pode usar para facilitar a troca de
estrutura de DOM.
<jfc-card-profile10-renderer ng-repeat="user in users"
ng-switch on="user.mode">
</jfc-card-profile10-renderer>
jfc-card-profile10-list.html
jfc-card-profile10-renderer.html
<jfc-card-profile10-view ng-switch-when="view"></jfc-card-profile10-view>
<jfc-card-profile10-edit ng-switch-when="edit"></jfc-card-profile10-edit>
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
Nossa directiva Renderer adiciona mais duas directivas em nosso projeto. View
e Edit.
jfc-card-profile10-renderer.html
<jfc-card-profile10-view ng-switch-when="view"></jfc-card-profile10-view>
<jfc-card-profile10-edit ng-switch-when="edit"></jfc-card-profile10-edit>
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
Nossa directiva View compartilha da mesma controladora que a Renderer. para isso usamos o atributo
require. O símbolo ^ indica que é obrigatório que jfcCardProfile10Renderer seja declarada em um parent
element e que a mesma possua uma controladora. Existem outros símbolos que podem ser passados no
require ( ?, ^^, ?^, ?^^ ). Olhe a documentação para mais detalhes.
jfc-card-profile10.js
.directive('jfcCardProfile10View', function(){
return {
restrict: 'E',
replace: true,
templateUrl: 'components/jfc-card-profile/jfc-card-profile10-view.html',
require: '^jfcCardProfile10Renderer',
link: function(scope, element, attrs, ctrl) {
scope.edit = function(){
ctrl.edit();
}
}
};
})
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
Agora que nossa directiva View compartilha da mesma controller da Renderer. Podemos acessar nossa
controladora através do quarto parâmetro.
jfc-card-profile10.js
.directive('jfcCardProfile10View', function(){
return {
restrict: 'E',
replace: true,
templateUrl: 'components/jfc-card-profile/jfc-card-profile10-view.html',
require: '^jfcCardProfile10Renderer',
link: function(scope, element, attrs, ctrl) {
scope.edit = function(){
ctrl.edit();
}
}
};
})
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
O mesmo acontece com nossa diretiva Edit.
jfc-card-profile10.js
.directive('jfcCardProfile10Edit', function(){
return {
restrict: 'E',
replace: true,
templateUrl: 'components/jfc-card-profile/jfc-card-profile10-edit.html',
require: '^jfcCardProfile10Renderer',
link: function(scope, element, attrs, ctrl) {
scope.save = function(){
ctrl.save();
}
}
};
});
@jandersonfc
10 - Complicando a vida e criando directivas
com dependência de outras directivas
E agora?
• Pense 2 vezes antes de criar um directiva. Evite criar directivas desnecessárias.
• Directiva é sempre muito útil, mas isso não significa que a forma como é criada hoje seja
prática. Por isso, evite criar directivas desnecessárias.
• No AngularJS 2 terá uma grande mudança na forma de criar directivas, e isso é muito
bom! então evite criar directivas desnecessárias.
• Polymer é outro projeto do Google que trabalha já com os Web Components. Não tenho
dúvida que web components é a melhor forma de criar componentes. Polymer terá
integração garantida no AngulaJS 2. Por favor, evite criar directivas desnecessárias.
• Essa apresentação e todo o material de apoio foi criado se baseando unicamente na
excelente documentação do AngularJS ( https://docs.angularjs.org/guide/directive ).
Mesmo assim, evite criar directivas desnecessárias. :P
• O material de apoio dessa apresentação pode ser acessada em
https://github.com/jandersonfc/tutorial-angularjs-directives
@jandersonfc