Расширение угловой директивы

Я хотел бы внести небольшие изменения в директиву третьей стороны (в частности, 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, я перезапишу свои изменения.

Итак, как мне расширить эту директиву отдельно от этого компонента бауэра?

113 голосов | спросил Kyle 9 J0000006Europe/Moscow 2013, 04:00:06

5 ответов


0

Вероятно, самый простой способ решить эту проблему - создать в вашем приложении директиву с тем же именем, что и у сторонней директивы. Обе директивы будут запущены, и вы можете указать их порядок выполнения, используя свойство priority (сначала выполняется более высокий приоритет).

Обе директивы будут совместно использовать область действия, и вы можете получить доступ и изменить область действия сторонней директивы с помощью метода link вашей директивы.

Вариант 2 . Вы также можете получить доступ к области действия сторонней директивы, просто поместив свою собственную произвольно именованную директиву в тот же элемент с ней (при условии, что ни одна из директив не использует изолирующую область). Все неизолированные директивы области видимости для элемента будут совместно использовать область видимости.

Дополнительная литература https://github.com/angular/angular.js/wiki/Dev-Guide%3A-Understanding-Directives

Примечание. Мой предыдущий ответ заключался в изменении стороннего сервиса, а не директивы.

ответил sh0ber 9 J0000006Europe/Moscow 2013, 04:51:28
0

TL; DR - дай мне демо!


Большая демо-кнопка


Используйте $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.

Некоторые заметки

  • Было предложено просто добавить директиву с тем же именем, а затем установить ее уровень приоритета. Помимо того, что он не является семантическим (что даже не является словом , я знаю…), он создает проблемы, например, что если уровень приоритета сторонней директивы изменится?

  • JeetendraChauhan заявил (хотя я не проверял его), что это решение не будет работать в версии 1.13.

ответил Eliran Malka 22 FebruaryEurope/MoscowbSat, 22 Feb 2014 20:04:30 +0400000000pmSat, 22 Feb 2014 20:04:30 +040014 2014, 20:04:30
0

Хотя это не является прямым ответом на ваш вопрос, вы можете знать, что последняя версия (в основном) http: //angular-ui.github.io/bootstrap/ добавлена ​​поддержка отключения вкладок. Эта функция была добавлена ​​через: https://github.com/angular-ui/bootstrap/commit/2b78dd16abd7e09846fa2ea1966/5/1606331321336_4

ответил pkozlowski.opensource 9 J0000006Europe/Moscow 2013, 14:24:53
0

Другое решение, в котором вы создаете новую директиву, которая расширяет ее без изменения исходной директивы

Решение похоже на решение для декоратора:

Создайте новую директиву и добавьте в качестве зависимости директиву, которую вы хотите расширить

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)
});

Таким образом, вы можете использовать оригинальную директиву и расширенную версию в одном приложении

ответил kidroca 3 MaramFri, 03 Mar 2017 02:50:26 +03002017-03-03T02:50:26+03:0002 2017, 02:50:26
0

Вот еще одно решение для другого сценария расширения привязок к директиве, которая имеет bindToController свойство.

Примечание. это не альтернатива другим решениям, которые были предложены здесь. Он решает только конкретный случай (не охваченный другими ответами), в котором исходная директива была настроена с помощью bindToController.

ответил gilad mayani 15 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 15 Sep 2016 16:00:01 +0300 2016, 16:00:01

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132