Gerard Gerard - 3 months ago 18
AngularJS Question

javascript, angularjs, can a ng-mouseover be inserted dynamically?

This code doesn't apparently work

var run_div = document.createElement('div');
run_div.className = 'whatever';
run_div.textContent = 'whatever';
run_div.setAttribute('ng-mouseover', 'console.log(\'ei\')');
document.getElementById('main_div').appendChild(run_div);


I guess it is because ng-mouseover hast to be there from the beginning so that AngularJS knows (?).
Is this the case? Is there any way to do this?




(below: UPDATE 1, UPDATE 2, UPDATE 3)

UPDATE 1:
This code works in a factory, where from the controller I call the factory method sending it the $scope

angular.module('whatever').controller('mycontroller',
['$scope', '$q', '$window', '$timeout',
function ($scope, $q, $window, $timeout) {

$scope.myfunction= function() {
myfactory.mymethod($scope);
};


And the factory calls the $compile in its definition

angular.module('whatever').factory('myfactory',
['$window', '$q', '$compile',
function($window, $q, $compile) {


...

mymethod = function($scope) {
var run_div = document.createElement('div');
run_div.className = 'whatever';
run_div.textContent = 'whatever';
run_div.setAttribute('ng-mouseover', 'console.log(\'ei\')');
document.getElementById('main_div').appendChild(run_div);
}


Which doesn't work, and then this throws an error

document.getElementById('main_div').appendChild($compile(run_div)($scope));
document.getElementById('main_div').appendChild($compile(run_div)($scope.new()));


or even

var run_div = angular.element(document.createElement('div'));
run_div.addClass('whatever');
run_div.attr('ng-mouseenter', 'console.log(\'ei\'');
document.getElementById('main_div').appendChild($compile(run_div)($scope));


where it complains that when appending, the parameter is not a node.

Uncaught (in promise) TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.(…)





UPDATE 2:

The following code shows (I think) that when compiling and appending from a factory it doesn't work, but when doing it from a controller, it works (see answer 2)

http://jsfiddle.net/xsaudasp/1/




UPDATE 3

I can see that this has to work, as shown here

http://jsfiddle.net/2uk2qe92/4/

Answer

First you need to create new $scope instance for your directive and then use $compile service to compile given div with that scope:

var directiveScope = $scope.$new();
var compiledDirective = $compile(run_div)(directiveScope);

Then you can append it to DOM:

angular.element('#my_dir').append(compiledDriective);

You must ensure that jQuery is loaded before angular so the jQuery selectors are availible. If you don't want to use jQuery you can use jqLite selector instead:

angular.element(document.querySelector('#my_dir')).append(compiledDirective)

Here is working jsfiddle of what you need: jsfiddle

Comments