En los casos en que tenga varias directivas sobre un único elemento DOM y donde el orden en el que se aplican sea importante, puede usar la priority
propiedad para ordenar su aplicación. Los números más altos se ejecutan primero. La prioridad predeterminada es 0 si no especifica una.
EDITAR : después de la discusión, aquí está la solución de trabajo completa. La clave era eliminar el atributo : element.removeAttr("common-things");
y también element.removeAttr("data-common-things");
(en caso de que los usuarios especifiquen data-common-things
en el html)
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true, //this setting is important, see explanation below
priority: 1000, //this setting is important, see explanation below
compile: function compile(element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
return {
pre: function preLink(scope, iElement, iAttrs, controller) { },
post: function postLink(scope, iElement, iAttrs, controller) {
$compile(iElement)(scope);
}
};
}
};
});
El programa de trabajo está disponible en: http://plnkr.co/edit/Q13bUt?p=preview
O:
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
priority: 1000,
link: function link(scope,element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
$compile(element)(scope);
}
};
});
MANIFESTACIÓN
Explicación de por qué tenemos que configurar terminal: true
y priority: 1000
(un número alto):
Cuando el DOM está listo, angular lo recorre para identificar todas las directivas registradas y compilar las directivas una por una en función de priority
si estas directivas están en el mismo elemento . Establecemos la prioridad de nuestra directiva personalizada en un número alto para asegurarnos de que se compile primero y con terminal: true
las otras directivas se omitirán después de que se compile esta directiva.
Cuando se compila nuestra directiva personalizada, modificará el elemento agregando directivas y eliminándose a sí mismo y usará el servicio $ compile para compilar todas las directivas (incluidas las que se omitieron) .
Si no configuramos terminal:true
y priority: 1000
, existe la posibilidad de que algunas directivas se compilen antes que nuestra directiva personalizada. Y cuando nuestra directiva personalizada usa $ compile para compilar el elemento => compila nuevamente las directivas ya compiladas. Esto provocará un comportamiento impredecible, especialmente si las directivas compiladas antes de nuestra directiva personalizada ya han transformado el DOM.
Para obtener más información sobre prioridad y terminal, consulte ¿Cómo entender el `terminal` de la directiva?
Un ejemplo de una directiva que también modifica la plantilla es ng-repeat
(prioridad = 1000), cuando ng-repeat
se compila, ng-repeat
haga copias del elemento de la plantilla antes de que se apliquen otras directivas .
Gracias al comentario de @ Izhaki, aquí está la referencia al ngRepeat
código fuente: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
RangeError: Maximum call stack size exceeded
medida que continúa compilando para siempre.