2015-07-22 5 views
3

Обычно директивы регистрируются на модуле с помощью метода directive:Динамически зарегистрировать директиву во время выполнения

.directive('MyDirective', function (MyDep) { 
    return { 
     restrict: 'E', 
     template: '<div></div>', 
     controller: function ($scope) { 
     } 
    } 
}); 

Однако, что если я динамически хочу зарегистрировать директивы во время выполнения? Например, предположим, что пользователь тянет следующие данные с сервера:

{ 
    directives: { 
     dir1: { 
      restrict: 'E', 
      template: '<div></div>', 
     }, 
     dir2: { 
      restrict: 'E', 
      template: '<div></div>', 
     } 
    } 
} 

Есть ли способ, что я могу взять эти данные использовать динамически регистрировать новые директивы для моего приложения? В случае успеха я должен иметь возможность динамически генерировать и $compile HTML, который зависит от них.

ответ

8

Это подмножество проблемы с «ленивой загрузкой угловых артефактов» (я изучил here и существуют и другие ресурсы). Идея состоит в том, чтобы использовать функцию config, чтобы «украсть» $compileProvider (ref), а затем позвонить по телефону $compileProvider.directive(...) по запросу, на основе ваших данных.

Грубый эскиз идеи:

var cachedCompileProvider; 
angular.module(...).config(['$compileProvider', function($compileProvider) { 
    cachedCompileProvider = $compileProvider; 
}); 

А потом (например, внутри где-нибудь, что имеет доступ к $http):

$http.get(...).then(function(response) { 
    angular.forEach(response.data.directives, function(dirDefinition, dirName) { 
     cachedCompileProvider.directive(dirName, dirDefinition); 
    }); 
}); 

(Конечно, вы не можете получить функции контроллера от Ответ JSON, как и выше, вам придется использовать другие методы - но, надеюсь, вы получите эту идею.)

+0

Спасибо, это действительно похоже, что это возможно. Я исправил недействительный JSON в моем вопросе (копирование-вставка делает странные вещи в мозг), но компилятор все же позволит мне добавить контроллер на стороне клиента, запуская что-то вроде 'dirDefinition.controller = function ($ scope) {/ ...}; '? – csvan

+1

Да, конечно, 'dirDefinition' является стандартным объектом определения директивы с контроллерами, функциями ссылок и т. Д. Просто вы не можете получить его из JSON из-за разумных ограничений этого формата. Вы * можете *, получить текстовый ответ, 'eval' it и использовать его в качестве определения директивы, если хотите (и чувствовать себя комфортно с' eval'). –

+0

Приятно, но посмотрите этот [plunkr] (https://plnkr.co/edit/nUOsDVq0eDxqyzkKEdm4), если вы сначала показываете список, а затем пытаетесь зарегистрировать директиву, уже скомпилированный шаблон не перекомпилируется, а если вы сначала зарегистрируете директиву, вы увидите он в действии при отображении списка – aleclofabbro

Смежные вопросы