Comprobar si existe un elemento con AngularJS y ejecutar una función solo si existe
Esta es la situación: Queremos ejecutar un plugin de JQuery sobre un elemento que se crea dinámicamente con un ng-repeat
dentro una plantilla de AngularJS. Es decir, no podemos inicializar el plugin hasta que se ha cargado la plantilla y se han creado los elementos.
Tenemos un controlador específico para dicha plantilla, por lo que realizando la comprobación aquí, solucionamos la primera parte del problema. Investigando un poco, veo que la solución más popular es asignar una directiva al ng-repeat
, que detectará cuando se ejecute la última iteración y lanzará un evento para ser recogido por el controlador, y entonces ya podríamos ahí ejecutar el plugin.
En Stackoverflow tenemos un ejemplo de esta aproximación, y en Nodewiz.biz tenemos otro ejemplo muy similar.
El caso es que esta aproximación me parece tremendamente rebuscada, aunque no dudo que cumple con el espíritu de AngularJS. Mi aproximación es más sencilla, aunque sospecho que no es del todo correcta, y me gustaría mejorarla con el tiempo:
$scope.bTooltipsterExists = false;
$scope.$watch(
function(){
if(angular.element('.tooltipster').length){
$scope.bTooltipsterExists = true;
return true;
}
return false;
},
function(){
if($scope.bTooltipsterExists){
$(".tooltipster").tooltipster({
trigger: 'click',
delay: 0
});
}
});
Básicamente tengo un $watch
que lo que hace es observar una función. Esta función busca los elementos que se crearán con el ng-repeat
y tendrán la clase .tooltipster
. La segunda función es la que se ejecuta cuando hay un cambio en el valor devuelto por la primera función. Es decir, cuando la primera función pase de devolver false
a devolver true
, se ejecutará el plugin.
Añado una segunda comprobación con la variable $scope.bTooltipsterExists
porque la primera vez que se ejecuta el $watch
, como no tiene una variable de referencia anterior, siempre se ejecuta la segunda función, y con esto lo evitamos.