Подтвердить что ты не робот

Angular $компиляция с требуемым контроллером

У меня есть составная директива списка - то есть элемент списка, который может быть самим списком.
Директива parent определяет контроллер:

.directive('parent', function() {
    controller: function($scope) {
    },
    link: function (scope, element, attrs) {
    }
})

В списке (элементов) требуется родительский контроллер, который сам по себе отлично работает (почему бы и нет):

.directive('list', function() {
     require: '^parent',
     link: function (scope, element, attrs, parentCtrl) {
     }
  })

То же самое относится и к конкретному элементу, что тоже прекрасно:

.directive('item', function() {
    require: '^parent',
    link: function (scope, element, attrs, parentCtrl) {
    }
})

Элемент может быть составным, и в этом случае он сам создает "список". Эта композиция выполняется $compile (ing) элементом списка внутри функции ссылки:

link: function (scope, element, attrs, parentCtrl) {
      ...
      $compile("<list></list>")(scope)
      ... 
}

Который выдает исключение:
Контроллер "родитель", требуемый директивным "списком", не может быть найден!

Причина этого очевидна - функция компиляции $не предоставила контроллер, и поэтому требование "родителя" не может быть разрешено.
И поэтому я попытался предоставить контроллер вручную:

$compile("<list></list>")(scope, null, {'parent': parentCtrl});

Это не вызывает исключение, но при необходимости не предоставляет этот контроллер.

Любая идея, как заставить функцию компиляции $принимать внешние контроллеры, которые также должны быть оценены?

4b9b3361

Ответ 1

Для дальнейшего использования, вот решение:

В функции компиляции $в качестве переводимого контроллера можно передать требуемый контроллер:

$compile(template)(scope, undefined, {transcludeControllers: injectedCtrl})

Если "injectedCtrl" - это объект, который перечисляет контроллеры, которые ожидает директива, например, если вы require: '^dad', то transcludeControllers выглядят следующим образом:

 transcludeControllers: {
        dad: { //name of controller in 'require' statement
          instance: vm //instance of controller
        }
      }

Смотрите этот пример: https://jsfiddle.net/qq4gqn6t/11/


Вот оно!

Ответ 2

У меня была аналогичная проблема, и, похоже, решение состоит в том, чтобы сначала добавить элемент в родительский элемент, а затем скомпилировать его.

.directive('item', function($compile) {
  return {
    template:'<li><a ng-click="addSubList()">Create Another List</a></li>',
    require: '^parent',
    replace: true,
    link: function(scope, element, attrs, parentCtrl) {

      scope.addSubList = function() {
        var sublist = angular.element('<ul list>');
        element.find('a').append(sublist);
        $compile(sublist)(scope);
      };

    }
  };
});

Смотрите этот Plunker: http://plnkr.co/edit/dASASrFbtXSMCRZKRAj5?p=preview

Ответ 3

$compile(angular.element("< list>< /list >"))(scope)