Why is it considered a bad idea to manipulate DOM in controllers?

5.3k views Asked by At

Many People have told me that it is a very bad thing to manipulate DOM in controllers, but what exactly is the reason. How does it affect the application that you are making? What are the Best Practices to do that and how is it done?

5

There are 5 answers

2
Pankaj Parkar On BEST ANSWER

Technically controller should be smaller & compact, it should not be playing with a DOM. Controller will only interested to have a business logic & binding level logic that are being called on events.

As per my perspective the reason behind "You should not manipulate DOM from the controller" is, It's just because of separation of concern. If you do the DOM manipulation from the controller then it gets tightly coupled to your controller, & that piece of code can't become reusable. So by writing that code in directive, the same code could be easily become a plug-able & reusable component. You can use the same DOM manipulation elsewhere just by putting directive tag/element.

Looked at directive definition, then you will analysed that it just meant to play with DOM, as it give a controller over DOM before rendering it using preLInk function & also post rendering of DOM you can get in postLink function.

Also directive make you available the directive element, you no need to make it compile because that element has already compiled with jQLite which is smaller version of jQuery used in angular. No need of selector here to get directive element DOM.

0
jordajm On

For most developers that come from a jQuery background, AngularJS requires a major mental shift.

The primary reason for not doing jQuery-style DOM manipulations when working with AngularJS is that your Angular app will be unaware of any changes you make to the DOM with jQuery, and so you won't be able to tie those DOM elements into any model without getting into major Angular hackery.

As for best practices, I would recommend taking on a full set of tutorials like those at http://codeschool.com to help you make the leap from the "jQuery mindset" to the pure Angular mindset.

The best thing I ever did as an angular developer was to remove the jQuery library from my Angular projects altogether so I wasn't tempted to return to my old and buggy ways.

But to answer your question more specifically, there are many ways to add elements to the DOM in an Angular app. I'd suggest that you post some code and a specific question if you're trying to figure out how to do something the "Angular Way".

The perfect example is something like jQuery's append() and remove(). These have no place in an Angular app because any element that is appended by jQuery won't be visible to Angular's models, making them useless to the app itself.

So, instead of appending and removing with jQuery, you'll probably want to either render the DOM elements with an ng-repeat directive (if there are multiple similar DOM elements that need to be appended) and add DOM elements by using ng-click to add data to the object that the ng-repeat directive is tied to, or if there aren't multiple similar elements to append, maybe you just need to use ng-show or ng-if to only render the DOM element after the click.

Here's an example of these two methods:
http://plnkr.co/edit/4MSOoTrGGom2DpGj00x4?p=preview

<body ng-controller="MainCtrl">
    <p ng-repeat="name in names">{{name}}</p>
    <form ng-submit="addName(newName)">
      <input ng-model="newName" type="text"/>
      <button type="submit">Add Name</button>
    </form>
    <br>
    <br>
    <h1 ng-show="showHeader">Header Element</h1>
    <button ng-show="!showHeader" ng-click="showHeader = !showHeader">Show Header</button>
    <button ng-show="showHeader" ng-click="showHeader = !showHeader">Hide Header</button>
  </body>

JS:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.names = ['Ramm', 'John', 'Keith', 'Susan', 'Janice'];

  $scope.addName = function(newName){
    $scope.names.push(newName);
  };

});
0
Sudhansu Choudhary On

You would manipulate DOM elements in a Directive. You got to understand these things,

  • Directives:- They are a powerful tool for working with and modifying the DOM .Angular defines directives as chunks of code you use for DOM manipulation

  • Controllers:- Controllers should be used purely to wire up services, dependencies and other objects, and assign them to the view via scope. They’re also an excellent choice when needing to handle complex business logic in your views.

  • Services:-services are mainly a way to communicate between controllers, but you can inject one service into another. services are often used as a way to get to your data stores

Please read these, directiveVsserviceVsController and when to use what?

0
Hyo Byun On

You are suppose to put the DOM manipulation in the directives & use angular data binding whenever possible to do DOM manipulation.

You CAN put all the DOM manipulation into a controller, but this often leads to a monolithic controller. Since there are patterns better suited to DOM manipulation through data binding & directives, you should take full advantage of them.

0
Carson Drake On

The simplest explanation is testability and reusability.

Controllers should contain only business logic. Putting any presentation logic into Controllers significantly affects its testability. Angular has databinding for most cases and directives to encapsulate manual DOM manipulation. Understanding Controllers