Angular ng-bind-html и директива внутри него
Plunker Link
У меня есть элемент, который я хотел бы связать с ним html.
<div ng-bind-html="details" upper></div>
Это работает. Теперь, наряду с этим, у меня также есть директива, которая привязана к связанному html:
$scope.details = 'Success! <a href="#/details/12" upper>details</a>'
Но директива upper
с div и anchor не оценивает. Как мне заставить работать?
Ответы
Ответ 1
Мне также пришлось столкнуться с этой проблемой, и после нескольких часов поиска в Интернете я прочитал комментарий @Chandermani, который оказался решением.
Вам нужно вызвать директиву "компиляция" с помощью этого шаблона:
HTML:
<div compile="details"></div>
JS:
.directive('compile', ['$compile', function ($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
// watch the 'compile' expression for changes
return scope.$eval(attrs.compile);
},
function(value) {
// when the 'compile' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
}
);
};
}])
Здесь вы можете увидеть рабочую .
Ответ 2
Спасибо за отличный ответ vkammerer. Одна оптимизация, которую я бы рекомендовал, - это не смотреть после компиляции. $Eval в выражении часов может иметь последствия для производительности.
angular.module('vkApp')
.directive('compile', ['$compile', function ($compile) {
return function(scope, element, attrs) {
var ensureCompileRunsOnce = scope.$watch(
function(scope) {
// watch the 'compile' expression for changes
return scope.$eval(attrs.compile);
},
function(value) {
// when the 'compile' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
// Use un-watch feature to ensure compilation happens only once.
ensureCompileRunsOnce();
}
);
};
}]);
Здесь вилка и обновленная скрипка.
Ответ 3
Добавьте эту директиву angular-bind-html-compile
.directive('bindHtmlCompile', ['$compile', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch(function () {
return scope.$eval(attrs.bindHtmlCompile);
}, function (value) {
// Incase value is a TrustedValueHolderType, sometimes it
// needs to be explicitly called into a string in order to
// get the HTML string.
element.html(value && value.toString());
// If scope is provided use it, otherwise use parent scope
var compileScope = scope;
if (attrs.bindHtmlScope) {
compileScope = scope.$eval(attrs.bindHtmlScope);
}
$compile(element.contents())(compileScope);
});
}
};
}]);
Используйте его так:
<div bind-html-compile="data.content"></div>
Действительно легко:)
Ответ 4
К сожалению, у меня недостаточно репутации для комментариев.
Я не мог заставить это работать целую вечность. Я изменил код ng-bind-html
, чтобы использовать эту настраиваемую директиву, но мне не удалось удалить $scope.html = $sce.trustAsHtml($scope.html)
, который был необходим для работы ng-bind-html. Как только я удалил это, функция компиляции начала работать.
Ответ 5
Для тех, кто имеет дело с контентом, который уже прошел через $sce.trustAsHtml
, вот что мне пришлось делать по-другому
function(scope, element, attrs) {
var ensureCompileRunsOnce = scope.$watch(function(scope) {
return $sce.parseAsHtml(attrs.compile)(scope);
},
function(value) {
// when the parsed expression changes assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current scope.
$compile(element.contents())(scope);
// Use un-watch feature to ensure compilation happens only once.
ensureCompileRunsOnce();
});
}
Это только часть link
директивы, поскольку я использую другой макет. Вам нужно будет ввести службу $sce
, а также $compile
.
Ответ 6
Лучшее решение, что я нашел! Я скопировал его и работал точно так, как мне было нужно. Спасибо, спасибо, спасибо...
в функции директивной ссылки у меня есть
app.directive('element',function($compile){
.
.
var addXml = function(){
var el = $compile('<xml-definitions definitions="definitions" />')($scope);
$scope.renderingElement = el.html();
}
.
.
и в шаблоне директивы:
<span compile="renderingElement"></span>