Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with DOM Manipulations in AngularJS

Tags:

angularjs

When I perform DOM manipulation (add new HTML) using jQuery, AngularJS doesn't automatically detect variables in the new HTML and replace them with their values. For example:

$scope.showSummary = function($event){      $($event.currentTarget).html("<div>{{row}}</div>");  }; 

This is a simple example, but after changing the HTML in the element (this function was called by ng-click), the output it still {{row}} instead of what row should mean in the context/scope.

like image 216
xd44 Avatar asked Jul 28 '12 08:07

xd44


People also ask

What is DOM manipulation in AngularJS?

When it comes to do DOM manipulation, binding event, etc... It happens, that we define functions that manipulates the DOM in a custom directive's link function, but we call it from the controller (we define functions in the $scope so it can be accessible by the given controller).

Where should we implement the DOM manipulation in AngularJS?

Where should we implement the DOM manipulation in AngularJS? In the directives. DOM Manipulations should not exist in controllers, services or anywhere else but in directives.

What is DOM manipulations?

DOM manipulation is the interaction of the JavaScript DOM API to modify or change the HTML document. With DOM manipulation, you can create, modify, style, or delete elements without a refresh. It also promotes user interactivity with browsers. You can use different programming languages to manipulate the DOM.


2 Answers

You have to inject $compile (http://docs.angularjs.org/api/ng.$compile) and use it so angular knows about the new html.

$compile('<div>{{row}}</div')($scope).appendTo($event.currentTarget);

However, it is frowned upon in angular to do DOM manipulation in your controllers. You want your controllers to handle business and your views to handle the view.

Try a directive to do what you want. http://docs.angularjs.org/guide/directive

like image 160
Andrew Joslin Avatar answered Sep 21 '22 13:09

Andrew Joslin


If you use fragments for new elements (e.g. $("<" + "div>").appendTo("body")), using a wrapper like the following for the JQuery prepend/append methods lets you avoid having to change your element-adding code:

// run angular-compile command on new content // (also works for prependTo/appendTo, since they use these methods internally) var oldPrepend = $.fn.prepend; $.fn.prepend = function() {     var isFragment = arguments[0][0] && arguments[0][0].parentNode && arguments[0][0].parentNode.nodeName == "#document-fragment";     var result = oldPrepend.apply(this, arguments);     if (isFragment)         AngularCompile(arguments[0]);     return result; }; var oldAppend = $.fn.append; $.fn.append = function() {     var isFragment = arguments[0][0] && arguments[0][0].parentNode && arguments[0][0].parentNode.nodeName == "#document-fragment";     var result = oldAppend.apply(this, arguments);     if (isFragment)         AngularCompile(arguments[0]);     return result; };  function AngularCompile(root) {     var injector = angular.element($('[ng-app]')[0]).injector();     var $compile = injector.get('$compile');     var $rootScope = injector.get('$rootScope');     var result = $compile(root)($rootScope);     $rootScope.$digest();     return result; } 
like image 33
Venryx Avatar answered Sep 23 '22 13:09

Venryx