Maplemx
Maplemx

Reputation: 73

data-binding doesn't work after using "appendChild()" to add new element

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

Answers (2)

m59
m59

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.

Live demos (click).

Upvotes: 2

Wottensprels
Wottensprels

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

Related Questions