angularjs - escape - ¿Cómo hago para angular.js reevaluar/recompilar inner html?
ng-bind-html angularjs (3)
Estoy haciendo una directiva que modifica su html interno. Código hasta el momento:
.directive(''autotranslate'', function($interpolate) {
return function(scope, element, attr) {
var html = element.html();
debugger;
html = html.replace(//[/[(/w+)/]/]/g, function(_, text) {
return ''<span translate="'' + text + ''"></span>'';
});
element.html(html);
}
})
Funciona, excepto que el html interno no se evalúa por angular. Quiero activar una revalorización del subárbol del element
. ¿Hay una manera de hacer eso?
Gracias :)
Aquí hay un método más genérico que desarrollé para resolver este problema:
angular.module(''kcd.directives'').directive(''kcdRecompile'', function($compile, $parse) {
''use strict'';
return {
scope: true, // required to be able to clear watchers safely
compile: function(el) {
var template = getElementAsHtml(el);
return function link(scope, $el, attrs) {
var stopWatching = scope.$parent.$watch(attrs.kcdRecompile, function(_new, _old) {
var useBoolean = attrs.hasOwnProperty(''useBoolean'');
if ((useBoolean && (!_new || _new === ''false'')) || (!useBoolean && (!_new || _new === _old))) {
return;
}
// reset kcdRecompile to false if we''re using a boolean
if (useBoolean) {
$parse(attrs.kcdRecompile).assign(scope.$parent, false);
}
// recompile
var newEl = $compile(template)(scope.$parent);
$el.replaceWith(newEl);
// Destroy old scope, reassign new scope.
stopWatching();
scope.$destroy();
});
};
}
};
function getElementAsHtml(el) {
return angular.element(''<a></a>'').append(el.clone()).html();
}
});
Lo usas así:
HTML
<div kcd-recompile="recompile.things" use-boolean>
<div ng-repeat="thing in ::things">
<img ng-src="{{::thing.getImage()}}">
<span>{{::thing.name}}</span>
</div>
</div>
JavaScript
$scope.recompile = { things: false };
$scope.$on(''things.changed'', function() { // or some other notification mechanism that you need to recompile...
$scope.recompile.things = true;
});
Editar
Si está viendo esto, recomendaría seriamente consultar la versión del sitio web ya que es probable que esté más actualizado.
Esto resultó funcionar incluso mejor que la solución de @ Reza
.directive(''autotranslate'', function() {
return {
compile: function(element, attrs) {
var html = element.html();
html = html.replace(//[/[(/w+)/]/]/g, function(_, text) {
return ''<span translate="'' + text + ''"></span>'';
});
element.html(html);
}
};
})
El código de Reza funciona cuando scope
es el alcance de todos sus elementos secundarios. Sin embargo, si hay un controlador ng o algo en uno de los nodos secundarios de esta directiva, las variables de ámbito no se encuentran. Sin embargo, con esta solución ^, ¡simplemente funciona!
Tienes que $compile
tu html interno como
.directive(''autotranslate'', function($interpolate, $compile) {
return function(scope, element, attr) {
var html = element.html();
debugger;
html = html.replace(//[/[(/w+)/]/]/g, function(_, text) {
return ''<span translate="'' + text + ''"></span>'';
});
element.html(html);
$compile(element.contents())(scope); //<---- recompilation
}
})