Расширение директивы Angular
Я хочу внести незначительные изменения в директиву сторонних разработчиков (в частности Angular UI Bootstrap). Я просто хочу добавить в область действия директивы 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
};
}]);
Но я также хочу сохранить Angular -Bootstrap в актуальном состоянии с Bower. Как только я запустил bower update
, я перезапишу свои изменения.
Итак, как я могу расширить эту директиву отдельно от этой компоненты Bower?
Ответы
Ответ 1
Вероятно, самый простой способ решить эту задачу - создать директиву для вашего приложения с тем же именем, что и директива третьей стороны. Обе директивы будут запущены, и вы можете указать их порядок выполнения, используя свойство priority
(сначала запускается более высокий приоритет).
Две директивы будут разделять область действия, и вы можете получить доступ и изменить область действия директивы третьей стороны с помощью вашего директивного метода link
.
Вариант 2:. Вы также можете получить доступ к областям директив сторонних разработчиков, просто поместив свою собственную условно названную директиву в один и тот же элемент (при условии, что ни одна из них не использует выделение области). Все директивы неизолированной области действия для элемента будут разделять область действия.
Дальнейшее чтение: https://github.com/angular/angular.js/wiki/Understanding-Directives#extending-directives
Примечание. Мой предыдущий ответ состоял в том, чтобы изменить стороннюю службу, а не директиву.
Ответ 2
TL; DR - демо-версия!
Big Demo Button
Используйте $provide
decorator()
, чтобы украсить стороннюю директиву.
В нашем случае мы можем расширить область действия так:
app.config(function($provide) {
$provide.decorator('paneDirective', function($delegate) {
var directive = $delegate[0];
angular.extend(directive.scope, {
disabled:'@'
});
return $delegate;
});
});
Сначала мы попросим украсить директиву pane
, передав его имя, объединенное с Directive
в качестве первого аргумента, затем мы извлекаем его из параметра обратного вызова (который представляет собой массив директив, соответствующих этому имени).
Как только мы его получим, мы сможем получить его объект области и продлить его по мере необходимости. Обратите внимание, что все это должно выполняться в блоке config
.
Некоторые примечания
-
Было предложено просто добавить директиву с тем же именем, а затем установить ее уровень приоритета. Помимо неземного (даже не слова, я знаю & hellip;), он создает проблемы, например. что, если изменяется уровень приоритета сторонней директивы?
-
JeetendraChauhan заявила (я ее еще не тестировал), что это решение не будет работать в версии 1.13.
Ответ 3
Хотя это не прямой ответ на ваш вопрос, вы можете захотеть узнать, что в последней версии (в мастер) http://angular-ui.github.io/bootstrap/ добавлена поддержка отключения вкладок. Эта функция была добавлена через:
https://github.com/angular-ui/bootstrap/commit/2b78dd16abd7e09846fa484331b5c35ece6619a2
Ответ 4
Другое решение, в котором вы создаете новую директиву, которая расширяет его, не изменяя исходную директиву
Решение похоже на решение декоратора:
Создайте новую директиву и введите в качестве зависимости директиву, которую вы хотите расширить
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)
});
Таким образом, вы можете использовать оригинальную директиву и расширенную версию в том же приложении
Ответ 5
Вот еще одно решение для другого сценария расширения привязок к директиве с свойством bindToController
.
Примечание. это не является альтернативой другим решениям, предлагаемым здесь. Он решает только конкретный случай (не рассматривается в других ответах), где исходная директива была настроена с помощью bindToController
.