Je voudrais apporter une modification mineure à une directive tierce (en particulier Angular UI Bootstrap ). Je veux simplement ajouter à la portée de la directive pane
:
angular.module('ui.bootstrap.tabs', [])
.controller('TabsController', ['$scope', '$element', function($scope, $element) {
// various methods
}])
.directive('tabs', function() {
return {
// etc...
};
})
.directive('pane', ['$parse', function($parse) {
return {
require: '^tabs',
restrict: 'EA',
transclude: true,
scope:{
heading:'@',
disabled:'@' // <- ADDED SCOPE PROPERTY HERE
},
link: function(scope, element, attrs, tabsCtrl) {
// link function
},
templateUrl: 'template/tabs/pane.html',
replace: true
};
}]);
Mais je souhaite également que Angular-Bootstrap soit à jour avec Bower. Dès que je lance bower update
, Je vais écraser mes modifications.
Alors, comment puis-je étendre cette directive séparément de cette composante de la tonnelle?
Le moyen le plus simple de résoudre ce problème consiste probablement à créer une directive portant le même nom que votre directive tierce sur votre application. Les deux directives seront exécutées et vous pouvez spécifier leur ordre d'exécution à l'aide de la propriété priority
(la priorité la plus élevée est exécutée en premier).
Les deux directives partageront la même portée et vous pouvez accéder à la portée de la directive tierce et la modifier via la méthode link
de votre directive.
Option 2: Vous pouvez également accéder à la portée d'une directive tierce en plaçant simplement votre propre directive nommée de manière arbitraire sur le même élément (en supposant qu'aucune de ces directives n'utilise isolat portée). Toutes les directives de portée non isolées sur un élément partagent la même portée.
Lectures supplémentaires: https://github.com/angular/angular.js/wiki/Dev-Guide%3A-Understanding-Directives
Remarque: Ma réponse précédente concernait la modification d'un service tiers, et non d'une directive.
TL; DR - Donne-moi cette démo!
Utilisez les decorator()
de $provide
Pour bien décorer la directive du tiers.
Dans notre cas, nous pouvons étendre le champ d'application de la directive comme suit:
app.config(function($provide) {
$provide.decorator('paneDirective', function($delegate) {
var directive = $delegate[0];
angular.extend(directive.scope, {
disabled:'@'
});
return $delegate;
});
});
Tout d'abord, nous demandons de décorer la directive pane
en passant son nom, concaténé avec Directive
comme premier argument, puis nous le récupérons à partir du paramètre callback (qui est un tableau de directives correspondant à ce nom). ).
Une fois que nous l'avons, nous pouvons obtenir son objet scope et l'étendre si nécessaire. Notez que tout cela doit être fait dans le bloc config
.
Il a été suggéré d'ajouter simplement une directive du même nom, puis de définir son niveau de priorité. En plus d'être peu sémantique (ce qui est même pas un mot , je sais…), cela pose des problèmes, par exemple. Et si le niveau de priorité de la directive tierce change?
JeetendraChauhan a affirmé (je ne l'ai pas encore testé) que cette solution ne fonctionnerait pas dans la version 1.13.
Bien que ce ne soit pas la réponse directe à votre question, vous voudrez peut-être savoir que la dernière version (en maître) de http://angular-ui.github.io/bootstrap/ prise en charge supplémentaire de la désactivation des onglets . Cette fonctionnalité a été ajoutée via: https://github.com/angular-ui/bootstrap/commit/2b78dd16abd7e09846fa484331b5c35ece6619a2
Une autre solution où vous créez une nouvelle directive qui l'étend sans modifier la directive d'origine
La solution est similaire à la solution de décorateur:
Créer une nouvelle directive et injecter comme dépendance la directive que vous souhaitez étendre
app.directive('extendedPane', function (paneDirective) {
// to inject a directive as a service append "Directive" to the directive name
// you will receive an array of directive configurations that match this
// directive (usually only one) ordered by priority
var configExtension = {
scope: {
disabled: '@'
}
}
return angular.merge({}, paneDirective[0], configExtension)
});
De cette façon, vous pouvez utiliser la directive d'origine et la version étendue dans la même application.
Voici une autre solution pour un scénario différent consistant à étendre les liaisons à une directive ayant la propriété bindToController
.
Remarque: Il ne s'agit pas d'une alternative aux autres solutions proposées ici. Cela ne résout qu'un cas spécifique (non traité dans d'autres réponses) dans lequel la directive d'origine a été configurée avec bindToController
.