Reputation: 73
when i write like this, angular works:
<html ng-app="mptmanager" class="ng-scope">
<body>
<input ng-model = "test" /><br />
{{test}}
</body>
</html>
<script src="js/angular.min.js"></script>
<script src="angular/angularModules.js"></script>
but when i run JS code like this:
var temp = document.createElement('div');
temp.innerHTML = '<input ng-model = "test2"><br />{{test2}}';
document.body.appendChild(temp);
angular has no effect to the new element, so i can only see "{{test2}}" on my page...
how can i make angular work when i try to add or change some element on my page with JS?
Upvotes: 0
Views: 3288
Reputation: 43755
You should never do DOM manipulation outside of directives when using Angular. Just to be complete, I'll show you how to make that work anyway. Just inject the $compile
service and compile the new markup with the scope.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $compile) {
$scope.foo = 'Default value';
var elem = document.createElement('div');
elem.innerHTML = '<input ng-model="foo">{{foo}}';
document.body.appendChild(elem);
$compile(elem)($scope);
});
Here are proper approaches using directives:
<div my-directive></div>
<div my-directive2></div>
JavaScript:
app.directive('myDirective', function() {
return {
template: '<input ng-model="foo">{{foo}}'
};
});
app.directive('myDirective2', function() {
return {
compile: function(element) {
element.html('<input ng-model="foo">{{foo}}');
}
};
});
In your directive, if you use the link
function, which has access to scope
, you will have to manually $compile
the markup as I demonstrated above, but be careful to avoid an infinite loop. You will usually do this: $compile(element.contents())(scope);
If you $compile the element itself, you would create an infinite loop.
Upvotes: 2
Reputation: 3327
As dskh briefly mentioned, directives are used to do that kind of stuff in Angular.
The issue here is that Angular doesn't know about the new element, as the routine which adds it lives outside of the Angular scope. You could call $scope.$apply()
manually, but i won't consider this best practice.
Upvotes: 0