@Alessanderrr
web-developer

AngularJS: Как сделать динамическое подключение директивы?

Доброго времени суток!
Суть проблемы в следующем:
Информация подгружается в модальные окна с помощью AJAX. Хочу по клику на элемент из списка передавать в контроллер название директивы. В создающемся модальном окне классу элемента присваиваю значение этой директивы, но окно открывается пустым. Если заранее прописать название директивы в класс, то окно придет заполненным. Искал информацию, везде про $compile написано, но вот как его приладить я не пойму. Кроме того, везде в примерах все написано хардкодом, весь html прямо в директиве, а я хочу чтобы весь html был в html-файлах, а JS был JSом.
Вызываю функцию открытия модального окна:
<span data-ng-click=showWindow("taxistoTablets")>Планшеты</span>

Контроллер, который создает модальное окно. pageName - передаваемое мной значение названия директивы
arm.controller("armController", function ($scope,$rootScope) {
    $scope.jqxWindowSettings = {
      maxHeight: 1000,
      maxWidth: 1000,
      minHeight: 350,
      minWidth: 350,
      height: 200,
      width: 200,
      resizable: true,
      isModal: false,
      autoOpen: false,
      collapsed: true,
      modalOpacity: 0
    };
    // show button click handler.
    $scope.showWindow = function (pageName) {
      $rootScope.jqxWindowSettings.apply('open');
      $rootScope.pageName = pageName;
    };
    // Ok button click handler.
    $scope.Ok = function () {
      $rootScope.jqxWindowSettings.apply('close');
    };
    // cancel button click handler.
    $scope.Cancel = function () {
      $rootScope.jqxWindowSettings.apply('close');
    };
    });
  });

Директива, которая в данном случае должна подключиться:
arm.directive("tablets", function () {
    return {
      controller: "getInfo",
      restrict: 'CA',
      templateUrl: 'tablets/info-description.html',
      scope: {
      },

      link: function ($scope, element, attributes) {
        $scope.formName = 'Планшеты';
      }
    }
  });

Код модального окна, в подставляется класс, через который должна подключаться директива, но она подключается только в случае, если я прописываю ее заранее, вручную. Динамически не хочет работать.
<jqx-window jqx-settings="jqxWindowSettings">
  <div>
    {{formName}}
  </div>
  <div>
    <div data-ng-controller="armController" id="modalWindowBody">
      <div data-ng-controller="getInfo">
        <div class="{{pageName}}"></div>
      </div>
    </div>
    <div>
      <div style="float: right; margin-top: 15px;">
        <jqx-button data-ng-click="Ok()" style="margin-right: 10px">Ok</jqx-button>
        <jqx-button data-ng-click="Cancel()">Cancel</jqx-button>
      </div>
    </div>
  </div>
</jqx-window>
  • Вопрос задан
  • 1154 просмотра
Решения вопроса 1
@Alessanderrr Автор вопроса
web-developer
Видимо, в моем случае возможен только "плохой вариант" - $compile.
Как я ни пытался по-другому приладить директиву на родину, ничего не вышло.
С помощью официальной доки сделал следующее:

Объявление модуля
var arm = angular.module("arm", ["jqwidgets"], function($compileProvider) {
  $compileProvider.directive('compile', function($compile) {
    return function(scope,element,attrs) {
      scope.$watch(
        function(scope){
          return scope.$eval(attrs.compile);
        },
        function (value) {
          element.html(value);
          $compile(element.contents())(scope);
        }
      );
    };
  });
});


В контроллере, который создает окно jqxwindow, определяем html:
$scope.showWindow = function (pageName) {
      $rootScope.jqxWindowSettings.apply('open');
      $rootScope.html = ('<div class="' + pageName + '"></div>');
};


После этого у меня в модальном окне стали динамически подгружаться нужные директивы в зависимости от значения pageName.
Думаю, что вышеприведенный код еще можно причесать для большей красоты, пока еще этим не занимался и не очень понимаю, как оно работает.. Но работает :)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
первый(правильный) вариант: Используйте стандартные механизмы роутинга angular для подгрузки таких темплейтов. Тогда и проблемы не будет.
второй(плохой) вариант: используйте сервис $compile
третий(что-то среднее между первым и вторым): использовать ng-include.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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