Добавьте директиву в модуль после начальной загрузки и применения к динамическому контенту
У меня есть веб-страница с определенным модулем (myModule), где я использую angularjs, используя
angular.bootstrap(element,[myModule.name]);
После нажатия кнопки, я добавляю динамический HTML и компилирую, используя
$compile('<my-element data="data"></my-element>',$scope.$new());
Директива добавляется с помощью
myModule.directive('myElement',function(){});
Проблема в том, что когда я добавляю директиву перед вызовом начальной загрузки, $compile завершает корректную обработку моей директивы. Однако, если директива добавлена после вызова bootstrap, $compile ничего не делает с моим html. Он просто добавляет класс ng-scope и директива / тег не обрабатывается.
В моем случае не все директивы будут загружены до вызова начальной загрузки. В случае, когда я загружаю директивы после вызова bootstrap, как мне использовать его на странице?
Благодарю.
Изменить: просто чтобы уточнить. Все директивы загружаются динамически. Те, которые я загружаю перед загрузкой, работают нормально. Те, которые я загружаю после неудачной загрузки. Когда я меняю местами загруженные директивы, я могу получить тот же результат, так что это не директивы, а то, что после начальной загрузки новые добавленные директивы, похоже, не вступают в силу.
2 ответа
При регистрации ленивых контроллеров или директив важно то, что вам нужно заполучить $ controllerProvider и $ compileProvider соответственно.
Это можно сделать только на этапе настройки, поэтому вы должны сохранять ссылки до тех пор, пока не загрузите контроллеры / директивы.
В последнее время я работал над отложенной загрузкой контроллера, сегодня я добавил поддержку директив, посмотрите мой код здесь:
https://github.com/matys84pl/angularjs-requirejs-lazy-controllers
в частности этот модуль lazy-directives.js
ПРИМЕЧАНИЕ: я использую RequireJS в своем проекте, однако применить решение к yepnope должно быть довольно просто.
Эта Fiddle демонстрирует, как динамически загружать / регистрировать и использовать:
- Угловые контроллеры (используя
$controllerProvider
) - Угловые директивы (используя
$compileProvider
) - Угловые частичные шаблоны (используя
$templateCache
)
Код: Настройка
// Initialize app.lazyController and app.lazyDirective.
// We will later use them to create controller and directives dynamically.
var app = angular.module('app', []);
app.config(function($controllerProvider, $compileProvider) {
// see page 12 of:
// http://www.slideshare.net/nirkaufman/angularjs-lazy-loading-techniques
app.lazyController = $controllerProvider.register;
// see: http://jsfiddle.net/8Bf8m/33/
app.lazyDirective = $compileProvider.directive;
});
// set of partials
var partials = [];
// store scope & templateCache, so we can dynamically insert partials
var scope, templateCache;
// define main controller
function MainCtrl($scope, $templateCache) {
$scope.partials = partials;
scope = $scope;
templateCache = $templateCache;
}
Код: Пример
var maxPartials = 3;
var i = 0;
var timer = setInterval(function() {
var i = partials.length;
app.lazyDirective('clickMe', function () { return {
link : function (scope, element) {
element.bind('click', function () {
alert('Clicked: ' + element.text());
});
},
};});
// define controller
var ctrlName = 'partial' + i + 'Ctrl';
app.lazyController(ctrlName, function($scope) {
$scope.text = 'hi ' + i;
});
// add partial template that I have available in string form
var newPartial = {
name: 'template' + i,
content: '<div ng-controller="' + ctrlName + '" class="a' + i + '">' +
'<input type="text" ng-model="text"></input>'+
'{{text}} <br/>' +
'<button click-me="">Click Me!</button>' +
'</div> <br/> <br/>'
};
partials[i] = newPartial;
// add template and notify angular of the content change
templateCache.put(partials[i].name, partials[i].content);
scope.$apply();
// stop timer
if (partials.length >= maxPartials) clearInterval(timer);
}, 1000);