Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 424
Vikram Singh Jadon Avatar asked Jun 24 '15 17:06

Vikram Singh Jadon


People also ask

Is it bad to manipulate the DOM in React?

No, it's a bad practice. React is using ref instead. But he doesn't even need to use refs in this case! refs should not be used for DOM manipulation like this.

What is the point of manipulating the DOM?

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.

Can we manipulate DOM?

The DOM stands for Document Object Model. It can simply be understood as a tree of nodes created by the browser. Each of these nodes has its own properties and methods which can be manipulated using JavaScript. The ability to manipulate the DOM is one of the most unique and useful abilities of JavaScript.

Why DOM manipulations are expensive?

When you're dealing with a client-side application, you quickly face one issue: DOM manipulation is expensive. If your application is big or very dynamic, the time spent in manipulating DOM elements rapidly adds up and you hit a performance bottleneck.


Video Answer


2 Answers

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);
  };

});
like image 190
jordajm Avatar answered Nov 14 '22 21:11

jordajm


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.

like image 44
Pankaj Parkar Avatar answered Nov 14 '22 22:11

Pankaj Parkar