Как подождать до конца $compile в angularJS
Я загружаю шаблон и компилирую его в свою область с помощью службы $compile
.
var template = "<div> .. {{someCompilingStuff}} ..</div>";
var compiled = $compile(template)(cellScope);
а затем используя его в popover
cellElement.popover({
html: true,
placement: "bottom",
trigger: "manual",
content: compiled
});
Мой шаблон довольно сложный и может потребоваться некоторое время для компиляции.
Как я могу убедиться, что angular закончил компиляцию шаблона, прежде чем использовать его в popover?
Изменить: я пытался заставить angular до $apply()
перед созданием popover, он работает, но генерирует ошибки JavaScript, которые не подходят для меня.
Ответы
Ответ 1
$compile
позволяет использовать так называемую функцию clone attach, которая позволяет прикрепить ваши элементы к документу. Вот пример, который вы можете использовать:
var template = "<div> .. {{someCompilingStuff}} ..</div>";
var compiled = $compile(template)(cellScope, function (clonedElement) {
cellElement.popover({
html: true,
placement: "bottom",
trigger: "manual",
content: clonedElement
});
});
Ссылка на Angular документацию об использовании компиляции
Ответ 2
Даже если будет возможно получить уведомление, когда функция компиляции/ссылки полностью отобразит шаблон, вы все равно не будете уверены, что браузер завершит внесение изменений в макет страницы в ответ. Возможно, вы сможете исправить свою проблему, введя небольшую задержку, используя $timeout
(setTimeout
), прежде чем запускать всплывающее окно. От чтения ответов на есть ли обратный вызов post render для Angular JS-директивы? Я думаю, что это могло бы исправить вашу проблему.
Ответ 3
В этих случаях вы, вероятно, хотели бы использовать $timeout
, чтобы исправить проблему.
Что-то вроде этого:
var template = "<div> .. {{someCompilingStuff}} ..</div>";
var compiled = $compile(template)(cellScope);
cellElement.popover({
html: true,
placement: "bottom",
trigger: "manual",
content: compiled
});
$timeout(function(){
cellElement.popover("show");
}, 0);
Вот пример JSFIDDLE, который я создал для вас. Посмотрите, как я показываю и скрываю popover с помощью $timeout
.
Ответ 4
Я собираюсь предоставить некодовый ответ (так что вы можете копать немного больше и узнать почему - плюс я чувствую себя ленивым в этот час):
Я бы рекомендовал использовать делегирование событий с другим родительским HTML-элементом в качестве делегата, с помощью которого вы можете вызвать метод popover. Просто включите class= "popover" в любые [родительские] элементы и скомпилируйте в нем шаблон. Вы можете выполнить/вызвать метод popover для этого родительского элемента. Однако я не совсем уверен, что вам не нужны дочерние элементы (из шаблона), так как я не знаю этого плагина. Однако я бы попробовал что-нибудь другое, кроме тайм-аута.
Моя надежда заключается в том, что этот ответ (возможно, неверный) ускоряет создание авторского решения (в результате получается чистый, надежный код) от автора.
Ответ 5
В качестве предложения вы можете создать службу компилятора, в которую вставляете компиляцию и создаете метод с параметром, принимающим html и область действия.
в этом методе используйте $отложенные и вызывают этот метод у вашего контроллера и разрешают вам перезвонить, что является обещанием, что компиляция выполнена.
сообщите мне, если он не работает для вас, я предоставил вам образцы кода.
Ответ 6
Я бы попытался обернуть компиляцию вашего шаблона внутри функции, которая возвращает обещание.
Что-то вроде этого:
function compile () {
var deferred = $q.defer();
/** simulate something sloooow (remove the setTimeout in your implementation) **/
setTimeout(function () {
deferred.resolve($compile('content')(scope));
}, 2000);
return deferred.promise;
}
// and then ...
compile().then(function (content) {
element.popover({
content: content
});
});
'наивный' jsbin && & && & & jsfiddle (изменено @Amir's)
Я не могу гарантировать, что это сработает для вашего конкретного случая, но стоит сделать это.