Nei casi in cui hai più direttive su un singolo elemento DOM e in cui l'ordine in cui sono applicati è importante, puoi utilizzare la priorityproprietà per ordinare la loro applicazione. I numeri più alti vengono eseguiti per primi. La priorità predefinita è 0 se non ne specifichi uno.
EDIT : dopo la discussione, ecco la soluzione di lavoro completa. La chiave era rimuovere l'attributo :, element.removeAttr("common-things");e anche element.removeAttr("data-common-things");(nel caso in cui gli utenti specifichino data-common-thingsnell'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);
}
};
}
};
});
Il plunker di lavoro è disponibile all'indirizzo: 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);
}
};
});
DEMO
Spiegazione del motivo per cui dobbiamo impostare terminal: truee priority: 1000(un numero elevato):
Quando il DOM è pronto, Angular accompagna il DOM per identificare tutte le direttive registrate e compilare le direttive una per una in base al fatto priority che queste direttive siano sullo stesso elemento . Impostiamo la priorità della nostra direttiva personalizzata su un numero elevato per garantire che venga compilata per prima e terminal: true, con le altre direttive, verranno ignorate dopo che questa direttiva è stata compilata.
Quando viene compilata la nostra direttiva personalizzata, modificherà l'elemento aggiungendo direttive e rimuovendo se stesso e utilizzando il servizio $ compile per compilare tutte le direttive (comprese quelle che sono state ignorate) .
Se non impostiamo terminal:truee priority: 1000, è possibile che alcune direttive vengano compilate prima della nostra direttiva personalizzata. E quando la nostra direttiva personalizzata usa $ compile per compilare l'elemento => compila di nuovo le direttive già compilate. Ciò causerà un comportamento imprevedibile soprattutto se le direttive compilate prima della nostra direttiva personalizzata hanno già trasformato il DOM.
Per maggiori informazioni su priorità e terminale, controlla Come capire il "terminale" della direttiva?
Un esempio di direttiva che modifica anche il modello è ng-repeat(priorità = 1000), quando ng-repeatviene compilato, ng-repeat crea copie dell'elemento modello prima che vengano applicate altre direttive .
Grazie al commento di @ Izhaki, ecco il riferimento al ngRepeatcodice sorgente: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
RangeError: Maximum call stack size exceededmentre continua a compilare per sempre.