create - ¿Cómo agregar elementos DOM(directivas angulares) a través de.append() de jQuery?
jquery create element (6)
¿Hay alguna manera de agregar un elemento que sea una directiva angular con métodos jQuery como append()
y hacer que Angular haga su compilación / vinculación para que funcione como si hubieras incluido la directiva en primer lugar?
Ejemplo:
app.directive(''myAngularDirective'', [function () {
...
// Lots of stuff in here; works when used normally but not when added via jQuery
});
$("body").append("<my-angular-directive />");
Actualmente solo agrega un elemento DOM vacío llamado "my-angular-directive", pero Angular no se activa y hace su magia.
El camino correcto es usar: $compile y en caso de que su directiva regrese: directive definition object
(que por cierto es el camino recomendado) puede llamar a la función de link
(para inyectar el scope
, por ejemplo).
$(''body'').append($compile("<my-angular-directive />")(scope));
scope.$apply();
Idealmente deberías evitar hacer eso.
Sin embargo, si realmente, realmente, realmente lo necesita, puede inyectar y usar el servicio $compile
seguido de un element.append
.
Si su directiva no necesita acceso a un alcance específico, puede incluso asignar el servicio $compile
y $rootScope
a la window
en la función de run
del módulo de su aplicación y luego usarlos fuera del contexto angular creando un nuevo scope
( $rootScope.new()
) y envuelve el elemento $rootScope.apply()
utilizando $rootScope.apply()
.
La respuesta aceptada no proporcionó un ejemplo completo, aquí hay una:
https://codepen.io/rhinojosahdz/pen/ZpGLZG
<body ng-app="app" ng-controller="Ctrl1 as ctrl1">
</body>
<script>
angular.module(''app'',[])
.controller(''Ctrl1'', [''$scope'', ''$compile'', function($scope, $compile){
var vm = this;
vm.x = 123;
$(''body'').append($compile("<hola x=''ctrl1.x'' />")($scope));
}])
.directive(''hola'', function(){
return {
template: ''<div ng-click="vm.alertXFromGivenScope()">click me!</div>''
,scope: {
x : ''=''
}
,controller: function(){
var vm = this;
vm.alertXFromGivenScope = function(){
alert(vm.x);
};
}
,controllerAs: ''vm''
,bindToController: true
}
})
<script>
Prueba esto
angular.element($("#appendToDiv")).append($compile("<my-angular-directive />")($scope));
Realmente quieres evitar hacer cualquier jquery si puedes, pero me encontré con un problema similar no hace mucho tiempo, aquí estaba mi pregunta y la respuesta correcta que debería ser capaz de ayudarte. La respuesta corta es usar $ compile.
Un ejemplo completo, de la documentación angular :
// Angular boilerplate
var app = angular.module("myApp", []);
app.controller("MyCtrl", function($scope) {
$scope.content = {
label: "hello, world!",
};
});
// Wrap the example in a timeout so it doesn''t get executed when Angular
// is first started.
setTimeout(function() {
// The new element to be added
var $div = $("<div ng-controller=''MyCtrl''>new: {{content.label}}</div>");
// The parent of the new element
var $target = $("[ng-app]");
angular.element($target).injector().invoke(function($compile) {
var $scope = angular.element($target).scope();
$target.append($compile($div)($scope));
// Finally, refresh the watch expressions in the new element
$scope.$apply();
});
}, 100);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">old: {{content.label}}</div>
</div>