Добавьте директиву в модуль после начальной загрузки и применения к динамическому контенту

У меня есть веб-страница с определенным модулем (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);
Другие вопросы по тегам