I'm relatively new to Angular and have begun writing my application with a component architecture. When looking through the Angular docs it recommends testing components with the $componentController mock method.
However, when I look at how directives have traditionally been tested in Angular pre-1.5 it looks like the preferred method was to use the $compile service to actually build your directive template-and-all. By using $compile you can make assertions about your template logic as well as the controller logic. Whereas with the $componentController method you can only test the controller logic, which doesn't actually seem all that useful since most complexity is found in templates and services.
Can someone shed some light on modern best practices? To me it makes more sense to use $compile so that you can test the template as well. But why do the Angular docs not mention this at all and instead recommend $componentController?
One of the biggest problems with AngularJS is that it has $scope. This is the place you put your bindings onto that are used in the DOM. It introduced much confusion.
Every good application design should have layers: business logic, UI etc. In AngularJS those layers pretty much corresponded to controller for business logic and directives for UI. However, because of the $scope being available in directives, many people decided to not use controllers and put all business logic in directives. This led to hard-to-test directives because they simultaneously implemented both layers. Also test became slow since DOM manipulation is slow.
Ideally, you should put as much testing as possible into business logic and less in the UI. Since framework handles synchronization between business logic and UI there is little possibility of bugs there. But business logic is where most bugs are introduced. That's why in the newer AngularJS they recommend to use $componentController to test business logic in controllers, not directives.
New Angular doesn't have $compile and most tests are written for controllers, which are implemented as classes there.
Related
It seems that there is a trend in eschewing designs which lend themselves to massive and unruly controllers for a more directive-based, granular design pattern--Angular 2 seems to be promoting this direction as well. I, admittedly, have rather large, non-DRY controllers in my angular apps, and wish to start using angular without relying on massive controllers and page-level scopes, but when I think about simply using directives for everything that I would have stuck in a controller the prospect of initiating and maintaining communication between relevant scopes, controlling scope inheritance, and keeping directives as modular as possible seems like I'm just thinking of directives as tiny, isolated controllers with an attached scope. Is this the wrong way to view this angular design pattern shift? How can I properly think about designing with directives if I am used to holding much of the logic in services / controllers? Is this still MVC or MVVW?
I know that this topic was discussed many times but I'm still not quite sure if I'm doing things right..
Many on-line resources embrace directives as a building blocks of the angular applications, in the same time many resources emphasize re-usability of the components. Anyway from my experience when I build typical app, there is not much things to re-use, usually each component has single role and it is used in the single place. As I understand angular, one of the main concepts is to provide semantic DOM, and in order to achieve that we can use directives. So when I build an angular app usually I create a set of directives and combine them in the views.
In my apps in the most cases all the DOM manipulation can be done using the build in directives. Most of my directives has a template and a controller, I do not need to use link function. In most of the resources in the internet I can read that I should use link function when creating directives. But this seems to be far more complicated code... . What is the benefit of the link function if I don't need any fancy DOM manipulations that are beyond build-in directives ?
tldr; I build my apps using directives with controllers and put them into views, is this a right approach ?
I've been developing in Angular over a year now on an enterprise level application and my team has gone by a standard of creating directives if you are using that same element more than once. It saves time, saves the DOM trouble, and makes it easy to create separate, testable pieces of code.
We've created directives for many listing items that use ng-repeat. Pretty much every ng-repeat we have is iterating over a directive to create true isolate scope in our elements' functionality. It's one of the most powerful features in AngularJS when done right and conforms to the standards of Object Oriented Programming where you can really make your applications use abstraction to the finest degree. Here's a wiki link on abstraction.
I have a general question. I've recently seen plenty of examples of people putting all their directive logic in a directive controller (and using it with controllerAs) instead of using link. I do see certain benefits in that:
The directive logic can be easily unit-tested.
You are seamlessly obligated to use the "dot notation" in your view model, thus prevent unexpected behavior.
As for the disadvantages - once the logic is inside the controller, it is exposed to other directives, as if encouraging developers of other directives to access those variables/methods, even if they are not meant to be accessed from outside.
I am interested in getting your take on this? How do you organize your code inside the directive.
Thanks
I am using Angular for about 4 months so I cannot
Say that I have too much experience. However in my
Personal experience I used the controller only for logic
That needs to be shared or executed before the link
Function. I guess you can hide some logic from your controller by using the module pattern and only exposing the logic that is really necessary. In my defense I haven't wrote really complicated controllers but this is the way I would go. (Sorry for my bad writing I am responding from my phone)
I'm a little confused about mvc frameworks for the web...take angular for example. Are the "views" in angular the (tweaked out) html and CSS and the "models" just javascript/json-like objects that contain data like regular Ajax data? It seems to me that this is how it is (maybe not in full detail, but roughly it seems like this is it). Does angular even use CSS? And I don't really understand the controller.
I know javascript to a degree where I am not a total beginner but these frameworks make no sense to me, it's like everyone is speaking Greek or something when I look up tutorials. It would help to know I'm sort of on the right track or whether my thinking is wrong, in a ballpark sense.
Help is highly appreciated. Thank you.
It sounds like you're on the right track. In Angular specifically, yes, the views are written declaratively in HTML and special tags and attributes called directives. Models can be anything; often you'll see examples in Angular that use plain JavaScript objects as the models, but in a more complex app you might have special objects that have methods specific to the application. Controllers are just there to tie the two together—they take the models and make them available to the view via the scope, and events (like ng-click) call methods on the controllers which make changes to the models.
AngularJS implements Model-View-Controller paradigm by connecting your HTML (views) to your JavaScript objects (models) via two-way data binding.
It extends HTML by providing directives that add functionality to your markup and allow you to create powerful dynamic templates. You can also create your own directives, crafting reusable components that fill your needs and abstracting away all the DOM manipulation logic. Like most JavaScript MVC frameworks, it lets you work with any server-side technology as long as it can serve your app through a RESTful web API.
You can find more info here:
http://www.angularjstutorial.com/
http://stephanebegaudeau.tumblr.com/post/48776908163/everything-you-need-to-understand-to-start-with
http://mrbool.com/mvc-in-angularjs/28962
I'm still learning AngularJS, but I'm not sure if having less control (via javascript) as I read is a good thing. I mean, everything is done via bindings through HTML code / attributes. How can I access $rootScope , or any of the services other than having them injected to my controllers via 'low level' javascript code?angular global variable doesn't hold much when logged to the console. What else to use to discover possible methods accessable via javascript?
I suspect this will be closed as opinion based but here is my opinion:
Angular does not remove your ability to control the page via javascript. Instead it isolates that code that manipulates the DOM. The learning curve for angular is a little like a roller coaster, in that you feel differently about the framework after learning a new piece. I felt really great after learning how templates and controllers worked but then felt low after seeing the limitations and complexities it created only to feel really great when I learned about Directives and how to manipulate the DOM through them. Six months into it, I am comfortable with Angular and would never go back to all the boilerplate of straight JQuery/javascript.
An important thing to keep in mind. Angular is not a UI library but rather a way of organizing your development files. There are many integration libraries of well known UI frameworks into angular Directives but by far the most popular is Twitter Bootstrap.
This blog post really nailed it: https://coderwall.com/p/3qclqg