AngularJS - why manipulating DOM in controller is a bad thing? - javascript

Its common knowledge that DOM manipulations should not be performed in AngularJS Controller, its very hard however to find why exactly is it a bad thing. All the sources say its difficult to test and because controller should be used for communication between directives, but fail to illustrate with code why this is a bad thing.
From my understanding I would think that controller, unlike directive, is not associated with any specific HTML, hence all the DOM modifications controller would do would very possibly fail. This would sure complicate development and testing.
Controller in directives being executed before link functions of child directives would also fail as the controller might not be aware of what the actual HTML of the child directives is. Link is executed after controller function and might modify HTML structure.
I hope I make sense here and if someone could clarify why manipulating DOM from controller is a bad thing, maybe some code exampleor link that explains it well that would be great.

The reason it is more difficult to prove their point with a code sample is that the reason can't really be represented by a short code snippet (short enough for Stack Overflow). It is really a maintainability precaution. Over the long term, you want to be able to independently alter the logic behind controllers and views independently, because otherwise a coupled controller and view pair tend to stay that way and limit each other in their ability to change their functionality without breaking the other. As soon as you decide to change anything about the view, you have the chance of making your controller code break without even touching it.
Testing becomes easier over time because the more tests you have, the more you wish that things were more modular and dependent on as little variables and parameters as possible.
Again, it is maintenance that drives this suggestion. The problems listed above might not be that bad starting out. But imagine adopting a project that you didn't build from the ground up and know all the intricacies behind the coupling between controller and view that hold this application together. What if your application reaches so many thousands of lines of code that it would be impossible for you to know all these intricacies even if you DID build it from the ground up?
For a more general understanding of why design patterns like the one you have alluded to are necessary, you can refer to this google search that will take you on a journey as long as you are willing to take. And for a general understanding of why design patterns even exist and why many people end up suggesting the same thing over and over again, you can refer to one of the catalysts to the introduction of design patterns, Christopher Alexander. He shows us that patterns are what they are because they work well and people repeat what works well.

If you look at the ever so popular question "Thinking in AngularJS" if I have a jQuery background? you will get some hints.
One of the biggest factor that i think DOM manipulation is neither needs nor done is because Angular uses declarative approach when it comes to DOM linking as against the imperative approach that you would use with direct DOM manipulation. Some of the answers detail this difference between declarative and imperative approach.
With jQuery you tell the DOM what needs to happen, step by step. With
AngularJS you describe what results you want but not how to do it.
More on this here. Also, check out Mark Rajcok's answer.
A more comprehensive treatment of this topic is also available here What is the difference between declarative and imperative programming
With such an approach the controller implementation is simplified, and we start to get real value as code base size grows and complexity increases.

My perspective is bit different and covers more than testing. It is the ability of the designer to have control over the HTML layout that otherwise would be taken over by writing code inside of the Angular Controller. Consider the following snippet (it is just a simple example)
<div ng-repeat="article in articles">
<p class="article-body">{{article.text}}</p>
</div>
This example just iterates over a collection and prints article in a separate paragraph tag. While it is certainly possible to loop over the collection in an Angular Controller and dynamically generate paragraph tags with text inside it. It will take away designer's capability to modify look & feel. Hence, If there is a requirement to show the article title, instead of doing this
<div ng-repeat="article in articles">
<span class="article-title">{{article.title}}</span>
<p class="article-body">{{article.text}}</p>
</div>
the designer will now have to locate Angular Controller code to modify DOM manipulation. Just compare above two approaches and guess which one will provide more flexibility.

Related

Showing modals: Angular directive/libraries VS direct native jQuery/bootstrap calls

I’ve been searching for the best way to handle modals in angular and I'm getting the impression that they need to be separated from controllers in order to achieve separation of concerns in MVC.
However when it comes to implementing this using a directive or a library out there I don't see the need for such massive overhead of adding so much code. Effectively it seems as though we are doing exactly the same thing but with more calls and events kicking off as compared to directly showing a bootstrap modal in the controller or service using jQuery as easy as:
$scope.saveChanges = function () {
$('#messageTitle').text('Done');
$('#messageText').text('Changes have been saved.');
$('#message').modal()
}
Porting a directive to handle the dialog is in effect showing the modal with additional steps and setups between dependencies etc. within angular, external libraries and/or custom code (whichever way it is applied). It's really like having a more simplified method call to a utilities method in some utils file that will just show the modal using jQuery. Again, I would be enlightened to know why this is not case which I expect from more experienced angular experts.
Apart from the fact that it is assumed a correct working way to do it, is there a reason why the DOM should not be referenced inside a controller. Could it have an effect on things like i.e. performance, buggy code, testing etc.?
I know that because it makes test cases easier is one of the reasons. Again, a valid reason however testing is not much of an issue having the DOM in business logic as in the code above if tested right. If there are, even more pressing cases for this, what are they? If any what is the best and most efficient way to achieve separation of the DOM from controllers/services if the same applies to services?
Background into current explanations:
What's the correct way to trigger jQuery DOM Manipulation from within a controller?
Separating DOM manipulation from Angular controllers - Best Practice wanted
AngularJS - why manipulating DOM in controller is a bad thing?
Why is it considered a bad idea to manipulate DOM in controllers?
From my understanding, these are the main reasons why a controller should not manipulate the DOM:
Testing. Test cases or test steps can be made well-structured and very easily testable when testing logic in controllers. Here what is tested is truly what a controller should be responsible for (Model manipulation).
Applying well-structured MVC code at the angular code base. Separation of concerns again gives a plus mark for testing but also makes code more manageable and well structured.
I would be happy to hear more detailed alternative answers to completely confirm and explain that any DOM manipulation what so ever is a bad thing within a controller. On the contrary it would be interesting to know whether there are exceptions. For the information of others and my attempt to answer, the reasons above are the most commonly known reasons and thus probably the only reasons to my knowledge, which fair enough are acceptable reasons at this point.

Using JavaScriptResult in my code

I have been wondering whether I should be using JavaScriptResult?
I have read couple articles about this and people have contradicting opinions.
I can see benefit:
Code is rendered in controller and therefore I can interact with my data sources and more difficult calculation and logic.
But JS rendered based on page using rendered jasonresult seem to be better choice.
Not sure about programming pattern:
How does JavaScript rendering in controller fits with Model View Controller
MVC is the design pattern which is all about separation of concern. I often hear that JavaScriptResult is something to avoid as it breaks that princple. In my opinion you should keep that in mind that MVC gives you powerful tools but it's up to you, what will you do with them. JavaScript XHR / Ajax can deliver more than only GUI renderring, but should be used with consideration. Well, fact is one can missuse even the simpliest methods, but that doesn't mean we shouldn't use them :)
Of course, using JavaScript on your page, and feeding it with JSON is perfectly fine and prefferable, in most of the cases it's sufficient. Sometimes though, you will need to choose wether you want to be 100% compliant with MVC pattern or DRY principle / other good practices. I think it's best to do what you think makes sense in a particular situation.
Let's take WebGrid helper's GetContainerUpdateScript method http://msdn.microsoft.com/en-us/library/system.web.helpers.webgrid.getcontainerupdatescript(v=vs.99).aspx it delivers jquery oneliner to update your webgrid data. In this case it's all in the View, but similar code could be a part of the controller - let's say a script that makes bunch of POST requests based on some unique identifier (sessionID-like for example).
In my opinion there are worse things than stepping on a thin red line between View and Controller (and sometimes crossing it slightly) to avoid other problems, make your code cleaner, more reusable and maintainable.

refactoring javascript. decouple markup or separate modules

I'm trying to make a large (~10K lines) javascript code base more maintainable. Pretty much all of the code is contained in one massive class. I want to do some refactoring, but I don't want to completely rewrite the code.
I have two ideas for how to re-organize the code, but I'm not sure which one is best. (I'm very open to other ideas too) What do you think about each of these approaches? How would you decide which is best?
Idea 1 – Decouple markup from business logic.
We have a somewhat complicated set of rules for what and how things should be displayed to users. This approach would split that into "What do we display?" and "How do we display it?"
Idea 2 – Break apart separate components into their own class.
There are several somewhat disjoint components in this code. If this code base were Facebook's – this approach would involve pulling apart the code for photos and the newsfeed.
If we are talking about Javascript, chances are you are using it in a browser. That being the case, most of your code is about views. A MVC pattern won't help you that much because most of your code will handle views.
Remember Javascript is not class based but prototype based. It is also functional. Functional programming excels in manipulating data. Try using the functional aspects of Javascript when doing so.
I suggest you try to split your project into a common framework for retrieving, manipulating and pushing data for all your views; and then splitting your view code into components.
If we are talking about 10k lines, you had to develop some sort of backbone to handle common tasks. If you don't use jQuery, after reorganizing your code, compare your implementation to jQuery's solutions and if you see an improvement, you can start refactoring inside your code.
If you have a chance take a look at Ext JS source code: http://www.sencha.com/products/extjs/download/ext-js-4.0.2a/213
To answer your question: Yes.
I'm not sure what you mean by 'refactor, but not rewrite'. Refactoring code shouldn't change external behaviour, but refactoring will certainly involve some sort of moving code around and whatnot.
Generally, separating the markup from the business logic is a good idea: it's following the model-view-controller pattern, effectively making your markup code 'view' code, and your business logic 'controller' code.
Breaking your code apart into separate components is likewise a good idea. Breaking your code into individual classes supports the idea of having classes with high cohesion and low coupling, and generally moves you towards more SOLID object-oriented design.
If you're asking which one will be more beneficial, that's something that can't be evaluated by the SO community, that's something you have to decide.
Oversimplified, you need to first figure out, in technical terms, what your desired architecture definition is. What is your main file (high-level) responsible for, what your low-scale modules are, and how they will be communicating (directly or vicariously). Should you abstract away the external frameworks at this stage? I am a fan of EDA's (Event-Driven Architectures), Fractal Hierarchies, and Mediation (Mediator Pattern), but many other definitions exist. Choose one that suits the scale of your project and can scale out.
Derive a blueprint and procedure for how you'll get your architecture from A to B. You may want an Abstract Procedure to entail a convention. For instance, "Redundancies: use Decorators" and so on. Do you favor composition over inheritance? However, you should have a Concrete Procedure for how to execute your game plan. E.g: "Replace references to 'X' with Mediator", "Let Save() dispatch a signal on the 'validation' channel", etc.
Make sure you're reflecting your views precisely with your JavaScript compositions. Because it's always a pain to balance unparallel hierarchies -- this ALWAYS leads to entropy. And try to embrace the (noted above) SOLID principles.
I wished to elaborate more, but I hope this is a good start for you.

Issues with web application

The previous programmer left the website in pretty unusable state, and I am having difficulty modifying anything. I am new to web design so I don't know whether my skills are a mismatch to this kind of job or is it normal in the real industry to have websites like these
The Home page includes three frames
Each of these frames have their own javascript functions ( between <head>, and also call other common javascript functions (using <script src=..>
Excessive usage of document.all - in fact the elements are referred or accessed by document.all only.
Excessive usage of XSLT and Web Services - Though I know that using Web Services is generally considered a good design choice - is there any other way I can consume these services other than using xslt. For example, the menu is created using the data returned by a web method.
Every <div>, <td> and every other element has an id, and these id's are manipulated by the javascript functions, and then some appropriate web service and the xslt files are loaded based on these..
From the security perspective, he used T-SQL's for xml auto for most of the data that is returned by the web service - is it a good choice from the security standpoint to expose the table names and column names to the end user??
I am a lot confused about the state of the application itself. Should I learn about the intricacies that he has developed and continue working on it, or should I start rewriting everything? What I am perplexed a lot is the lack of alternatives - and whether this is the common way web projects are handled in the real world or was it an exception?
Any suggestions, any pointers are welcome. Thanks
No, it is not acceptable in this industry that people keep writing un-maintainable code.
My advice to you is to go up the chain and convince everyone that this needs to be rewritten. If they question you, find an external consultant with relevant web development skills to review the application (for 1 day).
Keeping this website as-is, because it 'works' is like keeping a working model Ford-T car on today's highways, very dangerous. Security and maintenance costs are likely the most persuading topics to convince anyone against keeping this site 'as-is'.
Next, get yourself trained, it will pay off if you can rewrite this application knowing the basics. Todays technology (asp.net MVC) allows you to implement core business value faster than trying to maintain this unconventionally written app.
Tough spot for an inexperienced developer (or any) to be left in. I think you have a few hard weeks a head of you where you really need to read up on the technologies involved to get a better understanding of them and what is best practice. You will also need to really dig down into the existing code to understand how it all hangs together.
When you done all that you really need to think about your options. Usually re-writing something from scratch (especially if it actually works) is a bad idea. This obviously depend on the size of the project, for a smaller projects with only a couple of thousand lines of code it might be OK. When looking at someone elses code it is also easy to overlook that all that weird shit going on could actually be fixes for valid requirements. Things often start out looking neat, but then the real words comes visiting.
You will need to present the business with time estimates for re-writing to see if that is an option at all, but I'm guessing you will need to accept the way things are and do your best with what you have. Maybe you could gradually improves things.
I would recommend moving the project to MVC3 and rewriting the XSLT portions to function using views and/or partial views with MVC. The Razor model binding syntax is very clean and should be able to quickly cleave out the dirty XSLT code and be left with just the model properties you would need.
I would then have those web services invoked from MVC serverside and for you to deserialize the object results into real objects (or even just use straight XQuery or Json traversing to directly pull stuff out for your model) and bind those to your views.
This could be a rather gargantuan leap for technology at your company though. Some places have aversion to change.
I'd guess this was written 6-7 years ago, and hacked on since then. Every project accumulates a certain amount of bubble gum and duct tape. Sounds like this one's got it bad. I suggest breaking this up into bite size chunks. I assume that the site is actually working right now? So you don't want to break anything, the "business" often thinks "it was working just fine when the last guy was here."
Get a feel for your biggest pain points for maintaining the project, and what you'll get the biggest wins from fixing. a rewrite is great, if you have the time and support. But if it's a complex site, there's a lot to be said for a mature application. Mature in the sense that it fulfills the business needs, not that it's good code.
Also, working on small parts will get you better acquainted with the project and the business needs, so when you start the rewrite you'll have a better perspective.

How to abstract the data away from the design in web pages?

What are ways of keeping the data separate from the design of a webpage, so that if you redesign the site, or you want to provide the ability for users to customize the layout, it would be really easy to do so.
I think your question is confusing for most of others here. I see a lot of irrelevant answers coming up with "MVC" while you actually mean "separate content from style" instead of "separate data from design" which could be incorrectly interpreted as "separate model from view". The first part of your question indeed gives the impression that you're looking for MVC, but the second part of your question and the tags used made me realize that you actually didn't mean that.
The answer is simple: just don't use inline CSS (such as style="color:red") but have it in an entirely separate stylesheet which you include in the HTML head. Give the HTML elements sensible ID's and/or classnames. You can let the CSS hook on that. Also use HTML wisely and semantically. Separate the content in positionable block elements. Don't use tables for layout.
Certainly checkout the CSS Zen Garden as someone already mentioned before me. It uses exactly the same content (HTML code) throughout many different styles which you can select from a menu.
For more interesting blogs/links you may find those Google searches useful:
html semantics
css naming conventions
The same story also applies on JavaScript by the way. Do not use inline JS code, but just have it in an entirely separate file and make use of unobtrusive Javascript as many as possible. I.e. your website should still be useable without Javascript. The jQuery library is a perfect choice for that. Its selectors are also based on having sensible ID's and/or classnames.
The most common approach these days is to use the Model-View-Controller pattern.
Take a look at CSS Zen Garden and use the View Source feature.
I take this question as "provide the ability for users to customize the layout".
Such is the job of CSS, to provide "style" separate from HTML "markup".
With careful designs (with the stated goal in mind).
You can craft your markup so it'd can be really easy to style and re-style over and over.
It's not hard, I've done it a few times on a few redesigns.
You just need to stick to the semantics as much as possible.
On the backend, though, separating the model from the code is pretty much a nailed down science by now depending on what your backend infrastructure looks like and how far you want to go.
As David said, use the MVC pattern. But the biggest help is design the system early to avoid issues with bind your data (sources) to your interface. Make your interfaces so that you can change them out quickly etc.
The answers suggesting the use an MVC pattern are 100% right, and I encourage you to embrace it too.
More specifically, the kind of technology usually employed to obtain what you are seeking is the use of a templating system (such as Smarty if you use php, for example).
A web application framework (such as Cakephp, Rails or Django) can help you get started and achieve proper separation, usally with little effort.
The only drawback is that a change in approach and/or mentality may be required :)

Categories