After death of few Angular1 componets, The rest remain Same? - javascript

I am just curious to know, Is it like after the removal of few components like :
The rest off other components will remain same, because it is not mentioned in the image above
like:
Services,
Event (broadcast, emit, on)
run block
constant
config
And many others.
Hope the above question is valid, If so please give me idea about what is still remains , so that I feel easier in learning/adapting the new angular 2.
TypeScript:
I have seen the changes in class oriented block changes in typescript
like :
class MyComponent {
constructor() {
this.name = 'Max'
}
sayMyName() {
console.log('My name is', this.name)
}
}
Does that mean the commonly used DOM manipulation functions like
document.getElementBy
window object
And other things will same to an extent ?
Please give me some reference or idea about How much the Typescript has changed

Question 1:
The high-level abstraction is still the same (controllers, directives, services), but all the implementation details changed as the framework is rewritten in TypeScript.
For example, angular modules will be ditched in favour of ES6 native ones, which means run block, constant and config will not be relevant. Howevver, since they're keeping dependency injection, some way of configuration must exist, so whatever you can do in config and run will still be doable.
Question 2:
You probably confused TypeScript with JavaScript. The former has always had a syntax like that (so will the next version of JavaScript (ES6/harmony) to some extent).
However, the language change does not affect how you use the framework as TypeScript is supposed to be a superset of JavaScript, so most valid JS is also valid TS. You do not have to use features specific to TypeScript if you don't want to.

Based upon my understandings of how angular 2 is coming together this is how I see the other pieces fitting together.
Disclaimers
I am not a developer on the project, just a guy who is trying to keep up with the project as it is being developed.
The current state of angular 2 is alpha/developer preview and can/will change as development progresses
Overview
As angular 1.* progressed in its maturity there was a clear movement to utilizing conventional JavaScript patterns (see controllerAs, bindToController, no global controllers) and by following that convention your code for angular 1.* will be closer aligned to angular 2. The other movement that will assist you as you prepare for angular 2 is to think about your application in the idea of components (directive + controller with services injected in).
Services
These are classes that can be injected into components
Events (broadcast/emit)
These are a pub/sub implementation based upon the inherited $scope model which is not going to be present in angular 2, so another eventing model will need implemented. I have not heard this discussed from the angular team, so either be patient or pick another pub/sub model to implement.
Run block
With angular 2 being component based when the app is run is a direct correlation with the constructor of the root component (the one being bootstrapped)
Constants
Constants in angular 1 are just values that can be injected into other components, nothing has changed here and values can be injected into components in angular 2.
Config
With the angular module system going away in lieu of ES6 modules the idea of configuration (initializing values for a service) can be done in the constructor of the service. Also, angular 2 is going to support the idea of lazy loading additional components so configuration can be done later as well as upon application start
references
angular 2 project home page https://angular.io/
ng-conf videos https://www.youtube.com/user/ngconfvideos
angular 2 todo demo https://www.youtube.com/watch?v=uD6Okha_Yj0
angular 2 forms intro https://www.youtube.com/watch?v=4C4bmDOV5hk
getting started video https://www.youtube.com/watch?v=HmWm21cCAXM

Related

JQuery Datatables - 'No data available' (but data still showing) [duplicate]

Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 7 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Suppose I'm familiar with developing client-side applications in jQuery, but now I'd like to start using AngularJS. Can you describe the paradigm shift that is necessary? Here are a few questions that might help you frame an answer:
How do I architect and design client-side web applications differently? What is the biggest difference?
What should I stop doing/using; What should I start doing/using instead?
Are there any server-side considerations/restrictions?
I'm not looking for a detailed comparison between jQuery and AngularJS.
1. Don't design your page, and then change it with DOM manipulations
In jQuery, you design a page, and then you make it dynamic. This is because jQuery was designed for augmentation and has grown incredibly from that simple premise.
But in AngularJS, you must start from the ground up with your architecture in mind. Instead of starting by thinking "I have this piece of the DOM and I want to make it do X", you have to start with what you want to accomplish, then go about designing your application, and then finally go about designing your view.
2. Don't augment jQuery with AngularJS
Similarly, don't start with the idea that jQuery does X, Y, and Z, so I'll just add AngularJS on top of that for models and controllers. This is really tempting when you're just starting out, which is why I always recommend that new AngularJS developers don't use jQuery at all, at least until they get used to doing things the "Angular Way".
I've seen many developers here and on the mailing list create these elaborate solutions with jQuery plugins of 150 or 200 lines of code that they then glue into AngularJS with a collection of callbacks and $applys that are confusing and convoluted; but they eventually get it working! The problem is that in most cases that jQuery plugin could be rewritten in AngularJS in a fraction of the code, where suddenly everything becomes comprehensible and straightforward.
The bottom line is this: when solutioning, first "think in AngularJS"; if you can't think of a solution, ask the community; if after all of that there is no easy solution, then feel free to reach for the jQuery. But don't let jQuery become a crutch or you'll never master AngularJS.
3. Always think in terms of architecture
First know that single-page applications are applications. They're not webpages. So we need to think like a server-side developer in addition to thinking like a client-side developer. We have to think about how to divide our application into individual, extensible, testable components.
So then how do you do that? How do you "think in AngularJS"? Here are some general principles, contrasted with jQuery.
The view is the "official record"
In jQuery, we programmatically change the view. We could have a dropdown menu defined as a ul like so:
<ul class="main-menu">
<li class="active">
Home
</li>
<li>
Menu 1
<ul>
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Submenu 3</li>
</ul>
</li>
<li>
Menu 2
</li>
</ul>
In jQuery, in our application logic, we would activate it with something like:
$('.main-menu').dropdownMenu();
When we just look at the view, it's not immediately obvious that there is any functionality here. For small applications, that's fine. But for non-trivial applications, things quickly get confusing and hard to maintain.
In AngularJS, though, the view is the official record of view-based functionality. Our ul declaration would look like this instead:
<ul class="main-menu" dropdown-menu>
...
</ul>
These two do the same thing, but in the AngularJS version anyone looking at the template knows what's supposed to happen. Whenever a new member of the development team comes on board, she can look at this and then know that there is a directive called dropdownMenu operating on it; she doesn't need to intuit the right answer or sift through any code. The view told us what was supposed to happen. Much cleaner.
Developers new to AngularJS often ask a question like: how do I find all links of a specific kind and add a directive onto them. The developer is always flabbergasted when we reply: you don't. But the reason you don't do that is that this is like half-jQuery, half-AngularJS, and no good. The problem here is that the developer is trying to "do jQuery" in the context of AngularJS. That's never going to work well. The view is the official record. Outside of a directive (more on this below), you never, ever, never change the DOM. And directives are applied in the view, so intent is clear.
Remember: don't design, and then mark up. You must architect, and then design.
Data binding
This is by far one of the most awesome features of AngularJS and cuts out a lot of the need to do the kinds of DOM manipulations I mentioned in the previous section. AngularJS will automatically update your view so you don't have to! In jQuery, we respond to events and then update content. Something like:
$.ajax({
url: '/myEndpoint.json',
success: function ( data, status ) {
$('ul#log').append('<li>Data Received!</li>');
}
});
For a view that looks like this:
<ul class="messages" id="log">
</ul>
Apart from mixing concerns, we also have the same problems of signifying intent that I mentioned before. But more importantly, we had to manually reference and update a DOM node. And if we want to delete a log entry, we have to code against the DOM for that too. How do we test the logic apart from the DOM? And what if we want to change the presentation?
This a little messy and a trifle frail. But in AngularJS, we can do this:
$http( '/myEndpoint.json' ).then( function ( response ) {
$scope.log.push( { msg: 'Data Received!' } );
});
And our view can look like this:
<ul class="messages">
<li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>
But for that matter, our view could look like this:
<div class="messages">
<div class="alert" ng-repeat="entry in log">
{{ entry.msg }}
</div>
</div>
And now instead of using an unordered list, we're using Bootstrap alert boxes. And we never had to change the controller code! But more importantly, no matter where or how the log gets updated, the view will change too. Automatically. Neat!
Though I didn't show it here, the data binding is two-way. So those log messages could also be editable in the view just by doing this: <input ng-model="entry.msg" />. And there was much rejoicing.
Distinct model layer
In jQuery, the DOM is kind of like the model. But in AngularJS, we have a separate model layer that we can manage in any way we want, completely independently from the view. This helps for the above data binding, maintains separation of concerns, and introduces far greater testability. Other answers mentioned this point, so I'll just leave it at that.
Separation of concerns
And all of the above tie into this over-arching theme: keep your concerns separate. Your view acts as the official record of what is supposed to happen (for the most part); your model represents your data; you have a service layer to perform reusable tasks; you do DOM manipulation and augment your view with directives; and you glue it all together with controllers. This was also mentioned in other answers, and the only thing I would add pertains to testability, which I discuss in another section below.
Dependency injection
To help us out with separation of concerns is dependency injection (DI). If you come from a server-side language (from Java to PHP) you're probably familiar with this concept already, but if you're a client-side guy coming from jQuery, this concept can seem anything from silly to superfluous to hipster. But it's not. :-)
From a broad perspective, DI means that you can declare components very freely and then from any other component, just ask for an instance of it and it will be granted. You don't have to know about loading order, or file locations, or anything like that. The power may not immediately be visible, but I'll provide just one (common) example: testing.
Let's say in our application, we require a service that implements server-side storage through a REST API and, depending on application state, local storage as well. When running tests on our controllers, we don't want to have to communicate with the server - we're testing the controller, after all. We can just add a mock service of the same name as our original component, and the injector will ensure that our controller gets the fake one automatically - our controller doesn't and needn't know the difference.
Speaking of testing...
4. Test-driven development - always
This is really part of section 3 on architecture, but it's so important that I'm putting it as its own top-level section.
Out of all of the many jQuery plugins you've seen, used, or written, how many of them had an accompanying test suite? Not very many because jQuery isn't very amenable to that. But AngularJS is.
In jQuery, the only way to test is often to create the component independently with a sample/demo page against which our tests can perform DOM manipulation. So then we have to develop a component separately and then integrate it into our application. How inconvenient! So much of the time, when developing with jQuery, we opt for iterative instead of test-driven development. And who could blame us?
But because we have separation of concerns, we can do test-driven development iteratively in AngularJS! For example, let's say we want a super-simple directive to indicate in our menu what our current route is. We can declare what we want in the view of our application:
<a href="/hello" when-active>Hello</a>
Okay, now we can write a test for the non-existent when-active directive:
it( 'should add "active" when the route changes', inject(function() {
var elm = $compile( '<a href="/hello" when-active>Hello</a>' )( $scope );
$location.path('/not-matching');
expect( elm.hasClass('active') ).toBeFalsey();
$location.path( '/hello' );
expect( elm.hasClass('active') ).toBeTruthy();
}));
And when we run our test, we can confirm that it fails. Only now should we create our directive:
.directive( 'whenActive', function ( $location ) {
return {
scope: true,
link: function ( scope, element, attrs ) {
scope.$on( '$routeChangeSuccess', function () {
if ( $location.path() == element.attr( 'href' ) ) {
element.addClass( 'active' );
}
else {
element.removeClass( 'active' );
}
});
}
};
});
Our test now passes and our menu performs as requested. Our development is both iterative and test-driven. Wicked-cool.
5. Conceptually, directives are not packaged jQuery
You'll often hear "only do DOM manipulation in a directive". This is a necessity. Treat it with due deference!
But let's dive a little deeper...
Some directives just decorate what's already in the view (think ngClass) and therefore sometimes do DOM manipulation straight away and then are basically done. But if a directive is like a "widget" and has a template, it should also respect separation of concerns. That is, the template too should remain largely independent from its implementation in the link and controller functions.
AngularJS comes with an entire set of tools to make this very easy; with ngClass we can dynamically update the class; ngModel allows two-way data binding; ngShow and ngHide programmatically show or hide an element; and many more - including the ones we write ourselves. In other words, we can do all kinds of awesomeness without DOM manipulation. The less DOM manipulation, the easier directives are to test, the easier they are to style, the easier they are to change in the future, and the more re-usable and distributable they are.
I see lots of developers new to AngularJS using directives as the place to throw a bunch of jQuery. In other words, they think "since I can't do DOM manipulation in the controller, I'll take that code put it in a directive". While that certainly is much better, it's often still wrong.
Think of the logger we programmed in section 3. Even if we put that in a directive, we still want to do it the "Angular Way". It still doesn't take any DOM manipulation! There are lots of times when DOM manipulation is necessary, but it's a lot rarer than you think! Before doing DOM manipulation anywhere in your application, ask yourself if you really need to. There might be a better way.
Here's a quick example that shows the pattern I see most frequently. We want a toggleable button. (Note: this example is a little contrived and a skosh verbose to represent more complicated cases that are solved in exactly the same way.)
.directive( 'myDirective', function () {
return {
template: '<a class="btn">Toggle me!</a>',
link: function ( scope, element, attrs ) {
var on = false;
$(element).click( function () {
on = !on;
$(element).toggleClass('active', on);
});
}
};
});
There are a few things wrong with this:
First, jQuery was never necessary. There's nothing we did here that needed jQuery at all!
Second, even if we already have jQuery on our page, there's no reason to use it here; we can simply use angular.element and our component will still work when dropped into a project that doesn't have jQuery.
Third, even assuming jQuery was required for this directive to work, jqLite (angular.element) will always use jQuery if it was loaded! So we needn't use the $ - we can just use angular.element.
Fourth, closely related to the third, is that jqLite elements needn't be wrapped in $ - the element that is passed to the link function would already be a jQuery element!
And fifth, which we've mentioned in previous sections, why are we mixing template stuff into our logic?
This directive can be rewritten (even for very complicated cases!) much more simply like so:
.directive( 'myDirective', function () {
return {
scope: true,
template: '<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
link: function ( scope, element, attrs ) {
scope.on = false;
scope.toggle = function () {
scope.on = !scope.on;
};
}
};
});
Again, the template stuff is in the template, so you (or your users) can easily swap it out for one that meets any style necessary, and the logic never had to be touched. Reusability - boom!
And there are still all those other benefits, like testing - it's easy! No matter what's in the template, the directive's internal API is never touched, so refactoring is easy. You can change the template as much as you want without touching the directive. And no matter what you change, your tests still pass.
w00t!
So if directives aren't just collections of jQuery-like functions, what are they? Directives are actually extensions of HTML. If HTML doesn't do something you need it to do, you write a directive to do it for you, and then use it just as if it was part of HTML.
Put another way, if AngularJS doesn't do something out of the box, think how the team would accomplish it to fit right in with ngClick, ngClass, et al.
Summary
Don't even use jQuery. Don't even include it. It will hold you back. And when you come to a problem that you think you know how to solve in jQuery already, before you reach for the $, try to think about how to do it within the confines the AngularJS. If you don't know, ask! 19 times out of 20, the best way to do it doesn't need jQuery and to try to solve it with jQuery results in more work for you.
Imperative → declarative
In jQuery, selectors are used to find DOM elements and then bind/register event handlers to them. When an event triggers, that (imperative) code executes to update/change the DOM.
In AngularJS, you want to think about views rather than DOM elements. Views are (declarative) HTML that contain AngularJS directives. Directives set up the event handlers behind the scenes for us and give us dynamic databinding. Selectors are rarely used, so the need for IDs (and some types of classes) is greatly diminished. Views are tied to models (via scopes). Views are a projection of the model. Events change models (that is, data, scope properties), and the views that project those models update "automatically."
In AngularJS, think about models, rather than jQuery-selected DOM elements that hold your data. Think about views as projections of those models, rather than registering callbacks to manipulate what the user sees.
Separation of concerns
jQuery employs unobtrusive JavaScript - behavior (JavaScript) is separated from the structure (HTML).
AngularJS uses controllers and directives (each of which can have their own controller, and/or compile and linking functions) to remove behavior from the view/structure (HTML). Angular also has services and filters to help separate/organize your application.
See also https://stackoverflow.com/a/14346528/215945
Application design
One approach to designing an AngularJS application:
Think about your models. Create services or your own JavaScript objects for those models.
Think about how you want to present your models -- your views. Create HTML templates for each view, using the necessary directives to get dynamic databinding.
Attach a controller to each view (using ng-view and routing, or ng-controller). Have the controller find/get only whatever model data the view needs to do its job. Make controllers as thin as possible.
Prototypal inheritance
You can do a lot with jQuery without knowing about how JavaScript prototypal inheritance works. When developing AngularJS applications, you will avoid some common pitfalls if you have a good understanding of JavaScript inheritance. Recommended reading: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
AngularJS vs. jQuery
AngularJS and jQuery adopt very different ideologies. If you're coming from jQuery you may find some of the differences surprising. Angular may make you angry.
This is normal, you should push through. Angular is worth it.
The big difference (TLDR)
jQuery gives you a toolkit for selecting arbitrary bits of the DOM and making ad-hoc changes to them. You can do pretty much anything you like piece by piece.
AngularJS instead gives you a compiler.
What this means is that AngularJS reads your entire DOM from top to bottom and treats it as code, literally as instructions to the compiler. As it traverses the DOM, It looks for specific directives (compiler directives) that tell the AngularJS compiler how to behave and what to do. Directives are little objects full of JavaScript which can match against attributes, tags, classes or even comments.
When the Angular compiler determines that a piece of the DOM matches a particular directive, it calls the directive function, passing it the DOM element, any attributes, the current $scope (which is a local variable store), and some other useful bits. These attributes may contain expressions which can be interpreted by the Directive, and which tell it how to render, and when it should redraw itself.
Directives can then in turn pull in additional Angular components such as controllers, services, etc. What comes out the bottom of the compiler is a fully formed web application, wired up and ready to go.
This means that Angular is Template Driven. Your template drives the JavaScript, not the other way around. This is a radical reversal of roles, and the complete opposite of the unobtrusive JavaScript we have been writing for the last 10 years or so. This can take some getting used to.
If this sounds like it might be over-prescriptive and limiting, nothing could be farther from the truth. Because AngularJS treats your HTML as code, you get HTML level granularity in your web application. Everything is possible, and most things are surprisingly easy once you make a few conceptual leaps.
Let's get down to the nitty gritty.
First up, Angular doesn't replace jQuery
Angular and jQuery do different things. AngularJS gives you a set of tools to produce web applications. jQuery mainly gives you tools for modifying the DOM. If jQuery is present on your page, AngularJS will use it automatically. If it isn't, AngularJS ships with jQuery Lite, which is a cut down, but still perfectly usable version of jQuery.
Misko likes jQuery and doesn't object to you using it. However you will find as you advance that you can get a pretty much all of your work done using a combination of scope, templates and directives, and you should prefer this workflow where possible because your code will be more discrete, more configurable, and more Angular.
If you do use jQuery, you shouldn't be sprinkling it all over the place. The correct place for DOM manipulation in AngularJS is in a directive. More on these later.
Unobtrusive JavaScript with Selectors vs. Declarative Templates
jQuery is typically applied unobtrusively. Your JavaScript code is linked in the header (or the footer), and this is the only place it is mentioned. We use selectors to pick out bits of the page and write plugins to modify those parts.
The JavaScript is in control. The HTML has a completely independent existence. Your HTML remains semantic even without JavaScript. Onclick attributes are very bad practice.
One of the first things your will notice about AngularJS is that custom attributes are everywhere. Your HTML will be littered with ng attributes, which are essentially onClick attributes on steroids. These are directives (compiler directives), and are one of the main ways in which the template is hooked to the model.
When you first see this you might be tempted to write AngularJS off as old school intrusive JavaScript (like I did at first). In fact, AngularJS does not play by those rules. In AngularJS, your HTML5 is a template. It is compiled by AngularJS to produce your web page.
This is the first big difference. To jQuery, your web page is a DOM to be manipulated. To AngularJS, your HTML is code to be compiled. AngularJS reads in your whole web page and literally compiles it into a new web page using its built in compiler.
Your template should be declarative; its meaning should be clear simply by reading it. We use custom attributes with meaningful names. We make up new HTML elements, again with meaningful names. A designer with minimal HTML knowledge and no coding skill can read your AngularJS template and understand what it is doing. He or she can make modifications. This is the Angular way.
The template is in the driving seat.
One of the first questions I asked myself when starting AngularJS and running through the tutorials is "Where is my code?". I've written no JavaScript, and yet I have all this behaviour. The answer is obvious. Because AngularJS compiles the DOM, AngularJS is treating your HTML as code. For many simple cases it's often sufficient to just write a template and let AngularJS compile it into an application for you.
Your template drives your application. It's treated as a DSL. You write AngularJS components, and AngularJS will take care of pulling them in and making them available at the right time based on the structure of your template. This is very different to a standard MVC pattern, where the template is just for output.
It's more similar to XSLT than Ruby on Rails for example.
This is a radical inversion of control that takes some getting used to.
Stop trying to drive your application from your JavaScript. Let the template drive the application, and let AngularJS take care of wiring the components together. This also is the Angular way.
Semantic HTML vs. Semantic Models
With jQuery your HTML page should contain semantic meaningful content. If the JavaScript is turned off (by a user or search engine) your content remains accessible.
Because AngularJS treats your HTML page as a template. The template is not supposed to be semantic as your content is typically stored in your model which ultimately comes from your API. AngularJS compiles your DOM with the model to produce a semantic web page.
Your HTML source is no longer semantic, instead, your API and compiled DOM are semantic.
In AngularJS, meaning lives in the model, the HTML is just a template, for display only.
At this point you likely have all sorts of questions concerning SEO and accessibility, and rightly so. There are open issues here. Most screen readers will now parse JavaScript. Search engines can also index AJAXed content. Nevertheless, you will want to make sure you are using pushstate URLs and you have a decent sitemap. See here for a discussion of the issue: https://stackoverflow.com/a/23245379/687677
Separation of concerns (SOC) vs. MVC
Separation of concerns (SOC) is a pattern that grew up over many years of web development for a variety of reasons including SEO, accessibility and browser incompatibility. It looks like this:
HTML - Semantic meaning. The HTML should stand alone.
CSS - Styling, without the CSS the page is still readable.
JavaScript - Behaviour, without the script the content remains.
Again, AngularJS does not play by their rules. In a stroke, AngularJS does away with a decade of received wisdom and instead implements an MVC pattern in which the template is no longer semantic, not even a little bit.
It looks like this:
Model - your models contains your semantic data. Models are usually JSON objects. Models exist as attributes of an object called $scope. You can also store handy utility functions on $scope which your templates can then access.
View - Your views are written in HTML. The view is usually not semantic because your data lives in the model.
Controller - Your controller is a JavaScript function which hooks the view to the model. Its function is to initialise $scope. Depending on your application, you may or may not need to create a controller. You can have many controllers on a page.
MVC and SOC are not on opposite ends of the same scale, they are on completely different axes. SOC makes no sense in an AngularJS context. You have to forget it and move on.
If, like me, you lived through the browser wars, you might find this idea quite offensive. Get over it, it'll be worth it, I promise.
Plugins vs. Directives
Plugins extend jQuery. AngularJS Directives extend the capabilities of your browser.
In jQuery we define plugins by adding functions to the jQuery.prototype. We then hook these into the DOM by selecting elements and calling the plugin on the result. The idea is to extend the capabilities of jQuery.
For example, if you want a carousel on your page, you might define an unordered list of figures, perhaps wrapped in a nav element. You might then write some jQuery to select the list on the page and restyle it as a gallery with timeouts to do the sliding animation.
In AngularJS, we define directives. A directive is a function which returns a JSON object. This object tells AngularJS what DOM elements to look for, and what changes to make to them. Directives are hooked in to the template using either attributes or elements, which you invent. The idea is to extend the capabilities of HTML with new attributes and elements.
The AngularJS way is to extend the capabilities of native looking HTML. You should write HTML that looks like HTML, extended with custom attributes and elements.
If you want a carousel, just use a <carousel /> element, then define a directive to pull in a template, and make that sucker work.
Lots of small directives vs. big plugins with configuration switches
The tendency with jQuery is to write great big plugins like lightbox which we then configure by passing in numerous values and options.
This is a mistake in AngularJS.
Take the example of a dropdown. When writing a dropdown plugin you might be tempted to code in click handlers, perhaps a function to add in a chevron which is either up or down, perhaps change the class of the unfolded element, show hide the menu, all helpful stuff.
Until you want to make a small change.
Say you have a menu that you want to unfold on hover. Well now we have a problem. Our plugin has wired in our click handler for us, we're going to need to add a configuration option to make it behave differently in this specific case.
In AngularJS we write smaller directives. Our dropdown directive would be ridiculously small. It might maintain the folded state, and provide methods to fold(), unfold() or toggle(). These methods would simply update $scope.menu.visible which is a boolean holding the state.
Now in our template we can wire this up:
<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
Need to update on mouseover?
<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
The template drives the application so we get HTML level granularity. If we want to make case by case exceptions, the template makes this easy.
Closure vs. $scope
JQuery plugins are created in a closure. Privacy is maintained within that closure. It's up to you to maintain your scope chain within that closure. You only really have access to the set of DOM nodes passed in to the plugin by jQuery, plus any local variables defined in the closure and any globals you have defined. This means that plugins are quite self contained. This is a good thing, but can get restrictive when creating a whole application. Trying to pass data between sections of a dynamic page becomes a chore.
AngularJS has $scope objects. These are special objects created and maintained by AngularJS in which you store your model. Certain directives will spawn a new $scope, which by default inherits from its wrapping $scope using JavaScript prototypical inheritance. The $scope object is accessible in the controller and the view.
This is the clever part. Because the structure of $scope inheritance roughly follows the structure of the DOM, elements have access to their own scope, and any containing scopes seamlessly, all the way up to the global $scope (which is not the same as the global scope).
This makes it much easier to pass data around, and to store data at an appropriate level. If a dropdown is unfolded, only the dropdown $scope needs to know about it. If the user updates their preferences, you might want to update the global $scope, and any nested scopes listening to the user preferences would automatically be alerted.
This might sound complicated, in fact, once you relax into it, it's like flying. You don't need to create the $scope object, AngularJS instantiates and configures it for you, correctly and appropriately based on your template hierarchy. AngularJS then makes it available to your component using the magic of dependency injection (more on this later).
Manual DOM changes vs. Data Binding
In jQuery you make all your DOM changes by hand. You construct new DOM elements programatically. If you have a JSON array and you want to put it to the DOM, you must write a function to generate the HTML and insert it.
In AngularJS you can do this too, but you are encouraged to make use of data binding. Change your model, and because the DOM is bound to it via a template your DOM will automatically update, no intervention required.
Because data binding is done from the template, using either an attribute or the curly brace syntax, it's super easy to do. There's little cognitive overhead associated with it so you'll find yourself doing it all the time.
<input ng-model="user.name" />
Binds the input element to $scope.user.name. Updating the input will update the value in your current scope, and vice-versa.
Likewise:
<p>
{{user.name}}
</p>
will output the user name in a paragraph. It's a live binding, so if the $scope.user.name value is updated, the template will update too.
Ajax all of the time
In jQuery making an Ajax call is fairly simple, but it's still something you might think twice about. There's the added complexity to think about, and a fair chunk of script to maintain.
In AngularJS, Ajax is your default go-to solution and it happens all the time, almost without you noticing. You can include templates with ng-include. You can apply a template with the simplest custom directive. You can wrap an Ajax call in a service and create yourself a GitHub service, or a Flickr service, which you can access with astonishing ease.
Service Objects vs Helper Functions
In jQuery, if we want to accomplish a small non-dom related task such as pulling a feed from an API, we might write a little function to do that in our closure. That's a valid solution, but what if we want to access that feed often? What if we want to reuse that code in another application?
AngularJS gives us service objects.
Services are simple objects that contain functions and data. They are always singletons, meaning there can never be more than one of them. Say we want to access the Stack Overflow API, we might write a StackOverflowService which defines methods for doing so.
Let's say we have a shopping cart. We might define a ShoppingCartService which maintains our cart and contains methods for adding and removing items. Because the service is a singleton, and is shared by all other components, any object that needs to can write to the shopping cart and pull data from it. It's always the same cart.
Service objects are self-contained AngularJS components which we can use and reuse as we see fit. They are simple JSON objects containing functions and Data. They are always singletons, so if you store data on a service in one place, you can get that data out somewhere else just by requesting the same service.
Dependency injection (DI) vs. Instatiation - aka de-spaghettification
AngularJS manages your dependencies for you. If you want an object, simply refer to it and AngularJS will get it for you.
Until you start to use this, it's hard to explain just what a massive time boon this is. Nothing like AngularJS DI exists inside jQuery.
DI means that instead of writing your application and wiring it together, you instead define a library of components, each identified by a string.
Say I have a component called 'FlickrService' which defines methods for pulling JSON feeds from Flickr. Now, if I want to write a controller that can access Flickr, I just need to refer to the 'FlickrService' by name when I declare the controller. AngularJS will take care of instantiating the component and making it available to my controller.
For example, here I define a service:
myApp.service('FlickrService', function() {
return {
getFeed: function() { // do something here }
}
});
Now when I want to use that service I just refer to it by name like this:
myApp.controller('myController', ['FlickrService', function(FlickrService) {
FlickrService.getFeed()
}]);
AngularJS will recognise that a FlickrService object is needed to instantiate the controller, and will provide one for us.
This makes wiring things together very easy, and pretty much eliminates any tendency towards spagettification. We have a flat list of components, and AngularJS hands them to us one by one as and when we need them.
Modular service architecture
jQuery says very little about how you should organise your code. AngularJS has opinions.
AngularJS gives you modules into which you can place your code. If you're writing a script that talks to Flickr for example, you might want to create a Flickr module to wrap all your Flickr related functions in. Modules can include other modules (DI). Your main application is usually a module, and this should include all the other modules your application will depend on.
You get simple code reuse, if you want to write another application based on Flickr, you can just include the Flickr module and voila, you have access to all your Flickr related functions in your new application.
Modules contain AngularJS components. When we include a module, all the components in that module become available to us as a simple list identified by their unique strings. We can then inject those components into each other using AngularJS's dependency injection mechanism.
To sum up
AngularJS and jQuery are not enemies. It's possible to use jQuery within AngularJS very nicely. If you're using AngularJS well (templates, data-binding, $scope, directives, etc.) you will find you need a lot less jQuery than you might otherwise require.
The main thing to realise is that your template drives your application. Stop trying to write big plugins that do everything. Instead write little directives that do one thing, then write a simple template to wire them together.
Think less about unobtrusive JavaScript, and instead think in terms of HTML extensions.
My little book
I got so excited about AngularJS, I wrote a short book on it which you're very welcome to read online http://nicholasjohnson.com/angular-book/. I hope it's helpful.
Can you describe the paradigm shift that is necessary?
Imperative vs Declarative
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.
How do I architect and design client-side web apps differently?
AngularJS is an entire client-side framework that uses the MVC pattern (check out their graphical representation). It greatly focuses on separation of concerns.
What is the biggest difference? What should I stop doing/using; what should I start doing/using instead?
jQuery is a library
AngularJS is a beautiful client-side framework, highly testable, that combines tons of cool stuff such as MVC, dependency injection, data binding and much more.
It focuses on separation of concerns and testing (unit testing and end-to-end testing), which facilitates test-driven development.
The best way to start is going through their awesome tutorial. You can go through the steps in a couple of hours; however, in case you want to master the concepts behind the scenes, they include a myriad of reference for further reading.
Are there any server-side considerations/restrictions?
You may use it on existing applications where you are already using pure jQuery. However, if you want to fully take advantage of the AngularJS features you may consider coding the server side using a RESTful approach.
Doing so will allow you to leverage their resource factory, which creates an abstraction of your server side RESTful API and makes server-side calls (get, save, delete, etc.) incredibly easy.
To describe the "paradigm shift", I think a short answer can suffice.
AngularJS changes the way you find elements
In jQuery, you typically use selectors to find elements, and then wire them up:
$('#id .class').click(doStuff);
In AngularJS, you use directives to mark the elements directly, to wire them up:
<a ng-click="doStuff()">
AngularJS doesn't need (or want) you to find elements using selectors - the primary difference between AngularJS's jqLite versus full-blown jQuery is that jqLite does not support selectors.
So when people say "don't include jQuery at all", it's mainly because they don't want you to use selectors; they want you to learn to use directives instead. Direct, not select!
jQuery
jQuery makes ridiculously long JavaScript commands like getElementByHerpDerp shorter and cross-browser.
AngularJS
AngularJS allows you to make your own HTML tags/attributes that do things which work well with dynamic web applications (since HTML was designed for static pages).
Edit:
Saying "I have a jQuery background how do I think in AngularJS?" is like saying "I have an HTML background how do I think in JavaScript?" The fact that you're asking the question shows you most likely don't understand the fundamental purposes of these two resources. This is why I chose to answer the question by simply pointing out the fundamental difference rather than going through the list saying "AngularJS makes use of directives whereas jQuery uses CSS selectors to make a jQuery object which does this and that etc....". This question does not require a lengthy answer.
jQuery is a way to make programming JavaScript in the browser easier. Shorter, cross-browser commands, etc.
AngularJS extends HTML, so you don't have to put <div> all over the place just to make an application. It makes HTML actually work for applications rather than what it was designed for, which is static, educational web pages. It accomplishes this in a roundabout way using JavaScript, but fundamentally it is an extension of HTML, not JavaScript.
jQuery: you think a lot about 'QUERYing the DOM' for DOM elements and doing something.
AngularJS: THE model is the truth, and you always think from that ANGLE.
For example, when you get data from THE server which you intend to display in some format in the DOM, in jQuery, you need to '1. FIND' where in the DOM you want to place this data, the '2. UPDATE/APPEND' it there by creating a new node or just setting its innerHTML. Then when you want to update this view, you then '3. FIND' the location and '4. UPDATE'. This cycle of find and update all done within the same context of getting and formatting data from server is gone in AngularJS.
With AngularJS you have your model (JavaScript objects you are already used to) and the value of the model tells you about the model (obviously) and about the view, and an operation on the model automatically propagates to the view, so you don't have to think about it. You will find yourself in AngularJS no longer finding things in the DOM.
To put in another way, in jQuery, you need to think about CSS selectors, that is, where is the div or td that has a class or attribute, etc., so that I can get their HTML or color or value, but in AngularJS, you will find yourself thinking like this: what model am I dealing with, I will set the model's value to true. You are not bothering yourself of whether the view reflecting this value is a checked box or resides in a td element (details you would have often needed to think about in jQuery).
And with DOM manipulation in AngularJS, you find yourself adding directives and filters, which you can think of as valid HTML extensions.
One more thing you will experience in AngularJS: in jQuery you call the jQuery functions a lot, in AngularJS, AngularJS will call your functions, so AngularJS will 'tell you how to do things', but the benefits are worth it, so learning AngularJS usually means learning what AngularJS wants or the way AngularJS requires that you present your functions and it will call it accordingly. This is one of the things that makes AngularJS a framework rather than a library.
Those are some very nice, but lengthy answers.
To sum up my experiences:
Controllers and providers (services, factories, etc.) are for modifying the data model, NOT HTML.
HTML and directives define the layout and binding to the model.
If you need to share data between controllers, create a service or factory - they are singletons that are shared across the application.
If you need an HTML widget, create a directive.
If you have some data and are now trying to update HTML... STOP! update the model, and make sure your HTML is bound to the model.
jQuery is a DOM manipulation library.
AngularJS is an MV* framework.
In fact, AngularJS is one of the few JavaScript MV* frameworks (many JavaScript MVC tools still fall under the category library).
Being a framework, it hosts your code and takes ownership of decisions about what to call and when!
AngularJS itself includes a jQuery-lite edition within it. So for some basic DOM selection/manipulation, you really don't have to include the jQuery library (it saves many bytes to run on the network.)
AngularJS has the concept of "Directives" for DOM manipulation and designing reusable UI components, so you should use it whenever you feel the need of doing DOM manipulation related stuff (directives are only place where you should write jQuery code while using AngularJS).
AngularJS involves some learning curve (more than jQuery :-).
-->For any developer coming from jQuery background, my first advice would be to "learn JavaScript as a first class language before jumping onto a rich framework like AngularJS!"
I learned the above fact the hard way.
Good luck.
They're apples and oranges. You don't want to compare them. They're two different things. AngularJs has already jQuery lite built in which allows you to perform basic DOM manipulation without even including the full blown jQuery version.
jQuery is all about DOM manipulation. It solves all the cross browser pain otherwise you will have to deal with but it's not a framework that allows you to divide your app into components like AngularJS.
A nice thing about AngularJs is that it allows you to separate/isolate the DOM manipulation in the directives. There are built-in directives ready for you to use such as ng-click. You can create your own custom directives that will contain all your view logic or DOM manipulation so you don't end up mingle DOM manipulation code in the controllers or services that should take care of the business logic.
Angular breaks down your app into
- Controllers
- Services
- Views
- etc.
and there is one more thing, that's the directive. It's an attribute you can attach to any DOM element and you can go nuts with jQuery within it without worrying about your jQuery ever conflicts with AngularJs components or messes up with its architecture.
I heard from a meetup I attended, one of the founders of Angular said they worked really hard to separate out the DOM manipulation so do not try to include them back in.
Listen to the podcast JavaScript Jabber: Episode #32 that features the original creators of AngularJS: Misko Hevery & Igor Minar. They talk a lot about what it's like to come to AngularJS from other JavaScript backgrounds, especially jQuery.
One of the points made in the podcast made a lot of things click for me with respects to your question:
MISKO: [...] one of the things we thought about very hardly in Angular is, how do we provide lots of escape hatches so that you can get out and basically figure out a way out of this. So to us, the answer is this thing called “Directives”. And with directives, you essentially become a regular little jQuery JavaScript, you can do whatever you want.
IGOR: So think of directive as the instruction to the compiler that tells it whenever you come across this certain element or this CSS in the template, and you keep this kind of code and that code is in charge of the element and everything below that element in the DOM tree.
A transcript of the entire episode is available at the link provided above.
So, to directly answer your question: AngularJS is -very- opinionated and is a true MV* framework. However, you can still do all of the really cool stuff you know and love with jQuery inside of directives. It's not a matter of "How do I do what I used to in jQuery?" as much as it's a matter of "How do I supplement AngularJS with all of the stuff I used to do in jQuery?"
It's really two very different states of mind.
I find this question interesting, because my first serious exposure to JavaScript programming was Node.js and AngularJS. I never learned jQuery, and I guess that's a good thing, because I don't have to unlearn anything. In fact, I actively avoid jQuery solutions to my problems, and instead, solely look for an "AngularJS way" to solve them. So, I guess my answer to this question would essentially boil down to, "think like someone who never learned jQuery" and avoid any temptation to incorporate jQuery directly (obviously AngularJS uses it to some extent behind the scenes).
AngularJS and jQuery:
AngularJs and JQuery are completely different at every level except the JQLite functionality and you will see it once you start learning the AngularJs core features (I explained it below).
AngularJs is a client side framework that offers to build the independent client side application. JQuery is a client side library that play around the DOM.
AngularJs Cool Principle - If you want some changes on your UI think from model data change perspective. Change your data and UI will re-render itself. You need not to play around DOM each time unless and until it is hardly required and that should also be handled through Angular Directives.
To answer this question, I want to share my experience on the first enterprise application with AngularJS. These are the most awesome features that Angular provide where we start changing our jQuery mindset and we get the Angular like a framework and not the library.
Two-way data binding is amazing:
I had a grid with all functionality UPDATE, DELTE, INSERT. I have a data object that binds the grid's model using ng-repeat. You only need to write a single line of simple JavaScript code for delete and insert and that's it. grid automatically updates as the grid model changes instantly. Update functionality is real time, no code for it.
You feel amazing!!!
Reusable directives are super:
Write directives in one place and use it throughout the application. OMG!!! I used these directive for paging, regex, validations, etc. It is really cool!
Routing is strong:
It's up to your implementation how you want to use it, but it requires very few lines of code to route the request to specify HTML and controller (JavaScript)
Controllers are great:
Controllers take care of their own HTML, but this separation works well for common functionality well as. If you want to call the same function on the click of a button on master HTML, just write the same function name in each controller and write individual code.
Plugins:
There are many other similar features like showing an overlay in your app. You don't need to write code for it, just use an overlay plugin available as wc-overlay, and this will automatically take care of all XMLHttpRequest (XHR) requests.
Ideal for RESTful architecture:
Being a complete frameworks makes AngularJS great to work with a RESTful architecture. To call REST CRUD APIs is very easier and
Services: Write common codes using services and less code in controllers. Sevices can be used to share common functionalities among the controllers.
Extensibility: Angular has extended the HTML directives using angular directives. Write expressions inside html and evaluate them on runtime. Create your own directives and services and use them in another project without any extra effort.
As a JavaScript MV* beginner and purely focusing on the application architecture (not the server/client-side matters), I would certainly recommend the following resource (which I am surprised wasn't mentioned yet): JavaScript Design Patterns, by Addy Osmani, as an introduction to different JavaScript Design Patterns. The terms used in this answer are taken from the linked document above. I'm not going to repeat what was worded really well in the accepted answer. Instead, this answer links back to the theoretical backgrounds which power AngularJS (and other libraries).
Like me, you will quickly realize that AngularJS (or Ember.js, Durandal, & other MV* frameworks for that matter) is one complex framework assembling many of the different JavaScript design patterns.
I found it easier also, to test (1) native JavaScript code and (2) smaller libraries for each one of these patterns separately before diving into one global framework. This allowed me to better understand which crucial issues a framework adresses (because you are personally faced with the problem).
For example:
JavaScript Object-oriented Programming (this is a Google search link). It is not a library, but certainly a prerequisite to any application programming. It taught me the native implementations of the prototype, constructor, singleton & decorator patterns
jQuery/ Underscore for the facade pattern (like WYSIWYG's for manipulating the DOM)
Prototype.js for the prototype/ constructor/ mixin pattern
RequireJS/ Curl.js for the module pattern/ AMD
KnockoutJS for the observable, publish/subscribe pattern
NB: This list is not complete, nor 'the best libraries'; they just happen to be the libraries I used. These libraries also include more patterns, the ones mentioned are just their main focuses or original intents. If you feel something is missing from this list, please do mention it in the comments, and I will be glad to add it.
Actually, if you're using AngularJS, you don't need jQuery anymore. AngularJS itself has the binding and directive, which is a very good "replacement" for most things you can do with jQuery.
I usually develop mobile applications using AngularJS and Cordova. The ONLY thing from jQuery I needed is the Selector.
By googling, I see that there is a standalone jQuery selector module out there. It's Sizzle.
And I decided to make a tiny code snippet that help me quickly start a website using AngularJS with the power of jQuery Selector (using Sizzle).
I shared my code here: https://github.com/huytd/Sizzular

What is the correct place to inject/load a service that contains self-registering components?

I am working on an AngularJS application that has some self-registering components. Concretely, there are some services that do not directly offer any public interface themselves; they merely register some internal objects in some directory provided by another service.
You can imagine the body of such a service's factory as follows:
var internalThing = {
// members ...
};
thingRegistryService.registerThing(internalThing);
return {};
Thus, I only need to ensure that the service gets loaded at some point.
The dilemma I'm facing is as follows: As the service provides no public functions and just needs to "be there", there is no reason to inject it anywhere. As it does not get injected, it never gets instantiated. As it never gets instantiated, the components within the service never register themselves, though.
I can inject the service the usual where in some service or controller that I know will get loaded - but then, I am basically leaving an unused argument in the code (which, if it is the last argument in the list, will even get outlined as an error based on the project's JSHint settings).
Alternatively, I can do the self-registration in a method in the service and call that wherever I inject the service. This would make the service injection "useful", but in turn I'd have to deal with multiple calls myself instead of relying on the built-in singleton mechanism of AngularJS's services.
Or ... should I go yet another route, by providing a method like registerThing somewhere that takes the service name as a string, and that will internally just invoke $injector.get? Of course, that evokes the question again where the correct place to put that kind of call would be.
A little background: This is part of a large project developed in a large team. Build and/or deployment magic somehow handles that any JavaScript code file committed to our VCS by any developer will be available to AngularJS's dependency injection. Thus, any JavaScript that needs to be added has to be provided as some kind of an AngularJS service, controller, etc.
What is the proper way to load such a self-registering service?
Right place to init your module is angular.module('yourModule').run block.
In case of "self-registering" I think it is better to have some implicit method for this:
angular.module('yourModule').run(['service'], function (service) {
service.init();
})
If your build system magically provides all JS code, is an import needed?
A self-registering architecture as your build system suggests should not require imports. The import JSHint errors are the cost of this magic.
I've used a similar behavior with namespace-like design. It can be used for self-registering techniques, although imports get tricky and does not work well with ES6 modules.
This is close to my point: http://blog.assaf.co/automating-component-registration-in-angularjs/

Components and directives in angular 1.5

The big feature changes in Angular 1.5 are surrounding the support of components.
component('myComponent', {
template: '<h1>Hello {{ $ctrl.getFullName() }}</h1>',
bindings: { firstName: '<', lastName: '<' },
controller: function() {
this.getFullName = function() {
return this.firstName + ' ' + this.lastName;
};
}
});
While this is all good, I am not sure how this differs from directives.
What are the benefits of using components over traditional custom directives? And are components in Angular 1.5 and Angular 2 the same?
The .component DOES NOT replaces .directive like #rek Żelechowski said.
So..
There’s nothing you can do with .component() that you can’t do with .directive().
It aims to simplify the way we create “components” – which roughly means UI directives.
When can/should you use it?
Clearly there are a few cases where you can’t/shouldn’t use it:
If you need the link function (though you rarely should)
If you want a template-less directive, e.g. ng-click that doesn’t have a template or separate scope
For all your other directives, this should work. And because it saves on boilerplate and less error-prone it’s nicer to use.
Despite of all new goodies, .component() can’t fully replace .directive().
The .component is now preferred way of writing code because it favors good practices and gives developers ability to write code like in angular 2 (similar to Web Components). Basically, when you write code using component, upgrading to angular 2 will be easier. Functionalities remains almost the same. You should use .component always when it is possible.
Changes (extract)
component is declared using object instead of function
simplified isolated scope using binding property
components are always with isolated scope
some bad practices will not be possible
simpler, easier to understand configuration
lifecycle hooks: ($onInit(), $onChanges(changesObj), $doCheck(), $onDestroy(), $postLink())
Awesome article is here:
https://toddmotto.com/exploring-the-angular-1-5-component-method
When not to use Components (from docs):
for directives that need to perform actions in compile and pre-link functions, because they aren't available
when you need advanced directive definition options like priority, terminal, multi-element
when you want a directive that is triggered by an attribute or CSS class, rather than an element.
I believe, that the best description you can find is official guide: https://docs.angularjs.org/guide/component. It covers all changes, reasons for changes and gives you deep understanding of the components.
EDIT 01-2020:
I don't work on ng1 code anymore since at least a year
At the point of writing response (01-2017), impression that they are going to replace directives in most scenarios was correct. I removed a word "replaced" from the answer in 06-2017, because it is was indeed misleading at that point in time. However, since 1.5 you should still prefer components over directives when possible.
Actually, you should prefer not to use AngularJS at all. It is now in LTS and basically, only errors will be fixed. No new features. Also, LTS ends on 01-07-2021.
https://docs.angularjs.org/misc/version-support-status#long-term-support
PS. Using component instead of directive makes the code easier to port to ngx in the future.
Directives are NOT replaced, they just have been changed for lots of various reasons that might be a bit too much to get into here. The angular docs explain them pretty well, so you can start looking at the documentation there:
https://docs.angularjs.org/guide/component
To get a better idea of what the differences between directives and components are, I find that its better to reference the Angular 2.0 documentation. Angular 1.5 gave us a bridge to 2.0 that 1.4 and prior did not have. One of the bigger changes is removing $scope, another is providing Components as a way to build things (which is HIGHLY used in Angular 2.0).
All in all the very meat of the change is that it prepares the 1.X world to migrate to the 2.X world. In that world there are Components (which are element level directives at their heart), structural directives and attribute directives. See the below links to help understand each (along with the link provided above).
http://learnangular2.com/components/
https://angular.io/docs/ts/latest/guide/structural-directives.html
https://angular.io/docs/ts/latest/guide/attribute-directives.html

Angular app DOM manipulation best practices [duplicate]

Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 7 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Suppose I'm familiar with developing client-side applications in jQuery, but now I'd like to start using AngularJS. Can you describe the paradigm shift that is necessary? Here are a few questions that might help you frame an answer:
How do I architect and design client-side web applications differently? What is the biggest difference?
What should I stop doing/using; What should I start doing/using instead?
Are there any server-side considerations/restrictions?
I'm not looking for a detailed comparison between jQuery and AngularJS.
1. Don't design your page, and then change it with DOM manipulations
In jQuery, you design a page, and then you make it dynamic. This is because jQuery was designed for augmentation and has grown incredibly from that simple premise.
But in AngularJS, you must start from the ground up with your architecture in mind. Instead of starting by thinking "I have this piece of the DOM and I want to make it do X", you have to start with what you want to accomplish, then go about designing your application, and then finally go about designing your view.
2. Don't augment jQuery with AngularJS
Similarly, don't start with the idea that jQuery does X, Y, and Z, so I'll just add AngularJS on top of that for models and controllers. This is really tempting when you're just starting out, which is why I always recommend that new AngularJS developers don't use jQuery at all, at least until they get used to doing things the "Angular Way".
I've seen many developers here and on the mailing list create these elaborate solutions with jQuery plugins of 150 or 200 lines of code that they then glue into AngularJS with a collection of callbacks and $applys that are confusing and convoluted; but they eventually get it working! The problem is that in most cases that jQuery plugin could be rewritten in AngularJS in a fraction of the code, where suddenly everything becomes comprehensible and straightforward.
The bottom line is this: when solutioning, first "think in AngularJS"; if you can't think of a solution, ask the community; if after all of that there is no easy solution, then feel free to reach for the jQuery. But don't let jQuery become a crutch or you'll never master AngularJS.
3. Always think in terms of architecture
First know that single-page applications are applications. They're not webpages. So we need to think like a server-side developer in addition to thinking like a client-side developer. We have to think about how to divide our application into individual, extensible, testable components.
So then how do you do that? How do you "think in AngularJS"? Here are some general principles, contrasted with jQuery.
The view is the "official record"
In jQuery, we programmatically change the view. We could have a dropdown menu defined as a ul like so:
<ul class="main-menu">
<li class="active">
Home
</li>
<li>
Menu 1
<ul>
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Submenu 3</li>
</ul>
</li>
<li>
Menu 2
</li>
</ul>
In jQuery, in our application logic, we would activate it with something like:
$('.main-menu').dropdownMenu();
When we just look at the view, it's not immediately obvious that there is any functionality here. For small applications, that's fine. But for non-trivial applications, things quickly get confusing and hard to maintain.
In AngularJS, though, the view is the official record of view-based functionality. Our ul declaration would look like this instead:
<ul class="main-menu" dropdown-menu>
...
</ul>
These two do the same thing, but in the AngularJS version anyone looking at the template knows what's supposed to happen. Whenever a new member of the development team comes on board, she can look at this and then know that there is a directive called dropdownMenu operating on it; she doesn't need to intuit the right answer or sift through any code. The view told us what was supposed to happen. Much cleaner.
Developers new to AngularJS often ask a question like: how do I find all links of a specific kind and add a directive onto them. The developer is always flabbergasted when we reply: you don't. But the reason you don't do that is that this is like half-jQuery, half-AngularJS, and no good. The problem here is that the developer is trying to "do jQuery" in the context of AngularJS. That's never going to work well. The view is the official record. Outside of a directive (more on this below), you never, ever, never change the DOM. And directives are applied in the view, so intent is clear.
Remember: don't design, and then mark up. You must architect, and then design.
Data binding
This is by far one of the most awesome features of AngularJS and cuts out a lot of the need to do the kinds of DOM manipulations I mentioned in the previous section. AngularJS will automatically update your view so you don't have to! In jQuery, we respond to events and then update content. Something like:
$.ajax({
url: '/myEndpoint.json',
success: function ( data, status ) {
$('ul#log').append('<li>Data Received!</li>');
}
});
For a view that looks like this:
<ul class="messages" id="log">
</ul>
Apart from mixing concerns, we also have the same problems of signifying intent that I mentioned before. But more importantly, we had to manually reference and update a DOM node. And if we want to delete a log entry, we have to code against the DOM for that too. How do we test the logic apart from the DOM? And what if we want to change the presentation?
This a little messy and a trifle frail. But in AngularJS, we can do this:
$http( '/myEndpoint.json' ).then( function ( response ) {
$scope.log.push( { msg: 'Data Received!' } );
});
And our view can look like this:
<ul class="messages">
<li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>
But for that matter, our view could look like this:
<div class="messages">
<div class="alert" ng-repeat="entry in log">
{{ entry.msg }}
</div>
</div>
And now instead of using an unordered list, we're using Bootstrap alert boxes. And we never had to change the controller code! But more importantly, no matter where or how the log gets updated, the view will change too. Automatically. Neat!
Though I didn't show it here, the data binding is two-way. So those log messages could also be editable in the view just by doing this: <input ng-model="entry.msg" />. And there was much rejoicing.
Distinct model layer
In jQuery, the DOM is kind of like the model. But in AngularJS, we have a separate model layer that we can manage in any way we want, completely independently from the view. This helps for the above data binding, maintains separation of concerns, and introduces far greater testability. Other answers mentioned this point, so I'll just leave it at that.
Separation of concerns
And all of the above tie into this over-arching theme: keep your concerns separate. Your view acts as the official record of what is supposed to happen (for the most part); your model represents your data; you have a service layer to perform reusable tasks; you do DOM manipulation and augment your view with directives; and you glue it all together with controllers. This was also mentioned in other answers, and the only thing I would add pertains to testability, which I discuss in another section below.
Dependency injection
To help us out with separation of concerns is dependency injection (DI). If you come from a server-side language (from Java to PHP) you're probably familiar with this concept already, but if you're a client-side guy coming from jQuery, this concept can seem anything from silly to superfluous to hipster. But it's not. :-)
From a broad perspective, DI means that you can declare components very freely and then from any other component, just ask for an instance of it and it will be granted. You don't have to know about loading order, or file locations, or anything like that. The power may not immediately be visible, but I'll provide just one (common) example: testing.
Let's say in our application, we require a service that implements server-side storage through a REST API and, depending on application state, local storage as well. When running tests on our controllers, we don't want to have to communicate with the server - we're testing the controller, after all. We can just add a mock service of the same name as our original component, and the injector will ensure that our controller gets the fake one automatically - our controller doesn't and needn't know the difference.
Speaking of testing...
4. Test-driven development - always
This is really part of section 3 on architecture, but it's so important that I'm putting it as its own top-level section.
Out of all of the many jQuery plugins you've seen, used, or written, how many of them had an accompanying test suite? Not very many because jQuery isn't very amenable to that. But AngularJS is.
In jQuery, the only way to test is often to create the component independently with a sample/demo page against which our tests can perform DOM manipulation. So then we have to develop a component separately and then integrate it into our application. How inconvenient! So much of the time, when developing with jQuery, we opt for iterative instead of test-driven development. And who could blame us?
But because we have separation of concerns, we can do test-driven development iteratively in AngularJS! For example, let's say we want a super-simple directive to indicate in our menu what our current route is. We can declare what we want in the view of our application:
<a href="/hello" when-active>Hello</a>
Okay, now we can write a test for the non-existent when-active directive:
it( 'should add "active" when the route changes', inject(function() {
var elm = $compile( '<a href="/hello" when-active>Hello</a>' )( $scope );
$location.path('/not-matching');
expect( elm.hasClass('active') ).toBeFalsey();
$location.path( '/hello' );
expect( elm.hasClass('active') ).toBeTruthy();
}));
And when we run our test, we can confirm that it fails. Only now should we create our directive:
.directive( 'whenActive', function ( $location ) {
return {
scope: true,
link: function ( scope, element, attrs ) {
scope.$on( '$routeChangeSuccess', function () {
if ( $location.path() == element.attr( 'href' ) ) {
element.addClass( 'active' );
}
else {
element.removeClass( 'active' );
}
});
}
};
});
Our test now passes and our menu performs as requested. Our development is both iterative and test-driven. Wicked-cool.
5. Conceptually, directives are not packaged jQuery
You'll often hear "only do DOM manipulation in a directive". This is a necessity. Treat it with due deference!
But let's dive a little deeper...
Some directives just decorate what's already in the view (think ngClass) and therefore sometimes do DOM manipulation straight away and then are basically done. But if a directive is like a "widget" and has a template, it should also respect separation of concerns. That is, the template too should remain largely independent from its implementation in the link and controller functions.
AngularJS comes with an entire set of tools to make this very easy; with ngClass we can dynamically update the class; ngModel allows two-way data binding; ngShow and ngHide programmatically show or hide an element; and many more - including the ones we write ourselves. In other words, we can do all kinds of awesomeness without DOM manipulation. The less DOM manipulation, the easier directives are to test, the easier they are to style, the easier they are to change in the future, and the more re-usable and distributable they are.
I see lots of developers new to AngularJS using directives as the place to throw a bunch of jQuery. In other words, they think "since I can't do DOM manipulation in the controller, I'll take that code put it in a directive". While that certainly is much better, it's often still wrong.
Think of the logger we programmed in section 3. Even if we put that in a directive, we still want to do it the "Angular Way". It still doesn't take any DOM manipulation! There are lots of times when DOM manipulation is necessary, but it's a lot rarer than you think! Before doing DOM manipulation anywhere in your application, ask yourself if you really need to. There might be a better way.
Here's a quick example that shows the pattern I see most frequently. We want a toggleable button. (Note: this example is a little contrived and a skosh verbose to represent more complicated cases that are solved in exactly the same way.)
.directive( 'myDirective', function () {
return {
template: '<a class="btn">Toggle me!</a>',
link: function ( scope, element, attrs ) {
var on = false;
$(element).click( function () {
on = !on;
$(element).toggleClass('active', on);
});
}
};
});
There are a few things wrong with this:
First, jQuery was never necessary. There's nothing we did here that needed jQuery at all!
Second, even if we already have jQuery on our page, there's no reason to use it here; we can simply use angular.element and our component will still work when dropped into a project that doesn't have jQuery.
Third, even assuming jQuery was required for this directive to work, jqLite (angular.element) will always use jQuery if it was loaded! So we needn't use the $ - we can just use angular.element.
Fourth, closely related to the third, is that jqLite elements needn't be wrapped in $ - the element that is passed to the link function would already be a jQuery element!
And fifth, which we've mentioned in previous sections, why are we mixing template stuff into our logic?
This directive can be rewritten (even for very complicated cases!) much more simply like so:
.directive( 'myDirective', function () {
return {
scope: true,
template: '<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
link: function ( scope, element, attrs ) {
scope.on = false;
scope.toggle = function () {
scope.on = !scope.on;
};
}
};
});
Again, the template stuff is in the template, so you (or your users) can easily swap it out for one that meets any style necessary, and the logic never had to be touched. Reusability - boom!
And there are still all those other benefits, like testing - it's easy! No matter what's in the template, the directive's internal API is never touched, so refactoring is easy. You can change the template as much as you want without touching the directive. And no matter what you change, your tests still pass.
w00t!
So if directives aren't just collections of jQuery-like functions, what are they? Directives are actually extensions of HTML. If HTML doesn't do something you need it to do, you write a directive to do it for you, and then use it just as if it was part of HTML.
Put another way, if AngularJS doesn't do something out of the box, think how the team would accomplish it to fit right in with ngClick, ngClass, et al.
Summary
Don't even use jQuery. Don't even include it. It will hold you back. And when you come to a problem that you think you know how to solve in jQuery already, before you reach for the $, try to think about how to do it within the confines the AngularJS. If you don't know, ask! 19 times out of 20, the best way to do it doesn't need jQuery and to try to solve it with jQuery results in more work for you.
Imperative → declarative
In jQuery, selectors are used to find DOM elements and then bind/register event handlers to them. When an event triggers, that (imperative) code executes to update/change the DOM.
In AngularJS, you want to think about views rather than DOM elements. Views are (declarative) HTML that contain AngularJS directives. Directives set up the event handlers behind the scenes for us and give us dynamic databinding. Selectors are rarely used, so the need for IDs (and some types of classes) is greatly diminished. Views are tied to models (via scopes). Views are a projection of the model. Events change models (that is, data, scope properties), and the views that project those models update "automatically."
In AngularJS, think about models, rather than jQuery-selected DOM elements that hold your data. Think about views as projections of those models, rather than registering callbacks to manipulate what the user sees.
Separation of concerns
jQuery employs unobtrusive JavaScript - behavior (JavaScript) is separated from the structure (HTML).
AngularJS uses controllers and directives (each of which can have their own controller, and/or compile and linking functions) to remove behavior from the view/structure (HTML). Angular also has services and filters to help separate/organize your application.
See also https://stackoverflow.com/a/14346528/215945
Application design
One approach to designing an AngularJS application:
Think about your models. Create services or your own JavaScript objects for those models.
Think about how you want to present your models -- your views. Create HTML templates for each view, using the necessary directives to get dynamic databinding.
Attach a controller to each view (using ng-view and routing, or ng-controller). Have the controller find/get only whatever model data the view needs to do its job. Make controllers as thin as possible.
Prototypal inheritance
You can do a lot with jQuery without knowing about how JavaScript prototypal inheritance works. When developing AngularJS applications, you will avoid some common pitfalls if you have a good understanding of JavaScript inheritance. Recommended reading: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
AngularJS vs. jQuery
AngularJS and jQuery adopt very different ideologies. If you're coming from jQuery you may find some of the differences surprising. Angular may make you angry.
This is normal, you should push through. Angular is worth it.
The big difference (TLDR)
jQuery gives you a toolkit for selecting arbitrary bits of the DOM and making ad-hoc changes to them. You can do pretty much anything you like piece by piece.
AngularJS instead gives you a compiler.
What this means is that AngularJS reads your entire DOM from top to bottom and treats it as code, literally as instructions to the compiler. As it traverses the DOM, It looks for specific directives (compiler directives) that tell the AngularJS compiler how to behave and what to do. Directives are little objects full of JavaScript which can match against attributes, tags, classes or even comments.
When the Angular compiler determines that a piece of the DOM matches a particular directive, it calls the directive function, passing it the DOM element, any attributes, the current $scope (which is a local variable store), and some other useful bits. These attributes may contain expressions which can be interpreted by the Directive, and which tell it how to render, and when it should redraw itself.
Directives can then in turn pull in additional Angular components such as controllers, services, etc. What comes out the bottom of the compiler is a fully formed web application, wired up and ready to go.
This means that Angular is Template Driven. Your template drives the JavaScript, not the other way around. This is a radical reversal of roles, and the complete opposite of the unobtrusive JavaScript we have been writing for the last 10 years or so. This can take some getting used to.
If this sounds like it might be over-prescriptive and limiting, nothing could be farther from the truth. Because AngularJS treats your HTML as code, you get HTML level granularity in your web application. Everything is possible, and most things are surprisingly easy once you make a few conceptual leaps.
Let's get down to the nitty gritty.
First up, Angular doesn't replace jQuery
Angular and jQuery do different things. AngularJS gives you a set of tools to produce web applications. jQuery mainly gives you tools for modifying the DOM. If jQuery is present on your page, AngularJS will use it automatically. If it isn't, AngularJS ships with jQuery Lite, which is a cut down, but still perfectly usable version of jQuery.
Misko likes jQuery and doesn't object to you using it. However you will find as you advance that you can get a pretty much all of your work done using a combination of scope, templates and directives, and you should prefer this workflow where possible because your code will be more discrete, more configurable, and more Angular.
If you do use jQuery, you shouldn't be sprinkling it all over the place. The correct place for DOM manipulation in AngularJS is in a directive. More on these later.
Unobtrusive JavaScript with Selectors vs. Declarative Templates
jQuery is typically applied unobtrusively. Your JavaScript code is linked in the header (or the footer), and this is the only place it is mentioned. We use selectors to pick out bits of the page and write plugins to modify those parts.
The JavaScript is in control. The HTML has a completely independent existence. Your HTML remains semantic even without JavaScript. Onclick attributes are very bad practice.
One of the first things your will notice about AngularJS is that custom attributes are everywhere. Your HTML will be littered with ng attributes, which are essentially onClick attributes on steroids. These are directives (compiler directives), and are one of the main ways in which the template is hooked to the model.
When you first see this you might be tempted to write AngularJS off as old school intrusive JavaScript (like I did at first). In fact, AngularJS does not play by those rules. In AngularJS, your HTML5 is a template. It is compiled by AngularJS to produce your web page.
This is the first big difference. To jQuery, your web page is a DOM to be manipulated. To AngularJS, your HTML is code to be compiled. AngularJS reads in your whole web page and literally compiles it into a new web page using its built in compiler.
Your template should be declarative; its meaning should be clear simply by reading it. We use custom attributes with meaningful names. We make up new HTML elements, again with meaningful names. A designer with minimal HTML knowledge and no coding skill can read your AngularJS template and understand what it is doing. He or she can make modifications. This is the Angular way.
The template is in the driving seat.
One of the first questions I asked myself when starting AngularJS and running through the tutorials is "Where is my code?". I've written no JavaScript, and yet I have all this behaviour. The answer is obvious. Because AngularJS compiles the DOM, AngularJS is treating your HTML as code. For many simple cases it's often sufficient to just write a template and let AngularJS compile it into an application for you.
Your template drives your application. It's treated as a DSL. You write AngularJS components, and AngularJS will take care of pulling them in and making them available at the right time based on the structure of your template. This is very different to a standard MVC pattern, where the template is just for output.
It's more similar to XSLT than Ruby on Rails for example.
This is a radical inversion of control that takes some getting used to.
Stop trying to drive your application from your JavaScript. Let the template drive the application, and let AngularJS take care of wiring the components together. This also is the Angular way.
Semantic HTML vs. Semantic Models
With jQuery your HTML page should contain semantic meaningful content. If the JavaScript is turned off (by a user or search engine) your content remains accessible.
Because AngularJS treats your HTML page as a template. The template is not supposed to be semantic as your content is typically stored in your model which ultimately comes from your API. AngularJS compiles your DOM with the model to produce a semantic web page.
Your HTML source is no longer semantic, instead, your API and compiled DOM are semantic.
In AngularJS, meaning lives in the model, the HTML is just a template, for display only.
At this point you likely have all sorts of questions concerning SEO and accessibility, and rightly so. There are open issues here. Most screen readers will now parse JavaScript. Search engines can also index AJAXed content. Nevertheless, you will want to make sure you are using pushstate URLs and you have a decent sitemap. See here for a discussion of the issue: https://stackoverflow.com/a/23245379/687677
Separation of concerns (SOC) vs. MVC
Separation of concerns (SOC) is a pattern that grew up over many years of web development for a variety of reasons including SEO, accessibility and browser incompatibility. It looks like this:
HTML - Semantic meaning. The HTML should stand alone.
CSS - Styling, without the CSS the page is still readable.
JavaScript - Behaviour, without the script the content remains.
Again, AngularJS does not play by their rules. In a stroke, AngularJS does away with a decade of received wisdom and instead implements an MVC pattern in which the template is no longer semantic, not even a little bit.
It looks like this:
Model - your models contains your semantic data. Models are usually JSON objects. Models exist as attributes of an object called $scope. You can also store handy utility functions on $scope which your templates can then access.
View - Your views are written in HTML. The view is usually not semantic because your data lives in the model.
Controller - Your controller is a JavaScript function which hooks the view to the model. Its function is to initialise $scope. Depending on your application, you may or may not need to create a controller. You can have many controllers on a page.
MVC and SOC are not on opposite ends of the same scale, they are on completely different axes. SOC makes no sense in an AngularJS context. You have to forget it and move on.
If, like me, you lived through the browser wars, you might find this idea quite offensive. Get over it, it'll be worth it, I promise.
Plugins vs. Directives
Plugins extend jQuery. AngularJS Directives extend the capabilities of your browser.
In jQuery we define plugins by adding functions to the jQuery.prototype. We then hook these into the DOM by selecting elements and calling the plugin on the result. The idea is to extend the capabilities of jQuery.
For example, if you want a carousel on your page, you might define an unordered list of figures, perhaps wrapped in a nav element. You might then write some jQuery to select the list on the page and restyle it as a gallery with timeouts to do the sliding animation.
In AngularJS, we define directives. A directive is a function which returns a JSON object. This object tells AngularJS what DOM elements to look for, and what changes to make to them. Directives are hooked in to the template using either attributes or elements, which you invent. The idea is to extend the capabilities of HTML with new attributes and elements.
The AngularJS way is to extend the capabilities of native looking HTML. You should write HTML that looks like HTML, extended with custom attributes and elements.
If you want a carousel, just use a <carousel /> element, then define a directive to pull in a template, and make that sucker work.
Lots of small directives vs. big plugins with configuration switches
The tendency with jQuery is to write great big plugins like lightbox which we then configure by passing in numerous values and options.
This is a mistake in AngularJS.
Take the example of a dropdown. When writing a dropdown plugin you might be tempted to code in click handlers, perhaps a function to add in a chevron which is either up or down, perhaps change the class of the unfolded element, show hide the menu, all helpful stuff.
Until you want to make a small change.
Say you have a menu that you want to unfold on hover. Well now we have a problem. Our plugin has wired in our click handler for us, we're going to need to add a configuration option to make it behave differently in this specific case.
In AngularJS we write smaller directives. Our dropdown directive would be ridiculously small. It might maintain the folded state, and provide methods to fold(), unfold() or toggle(). These methods would simply update $scope.menu.visible which is a boolean holding the state.
Now in our template we can wire this up:
<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
Need to update on mouseover?
<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
The template drives the application so we get HTML level granularity. If we want to make case by case exceptions, the template makes this easy.
Closure vs. $scope
JQuery plugins are created in a closure. Privacy is maintained within that closure. It's up to you to maintain your scope chain within that closure. You only really have access to the set of DOM nodes passed in to the plugin by jQuery, plus any local variables defined in the closure and any globals you have defined. This means that plugins are quite self contained. This is a good thing, but can get restrictive when creating a whole application. Trying to pass data between sections of a dynamic page becomes a chore.
AngularJS has $scope objects. These are special objects created and maintained by AngularJS in which you store your model. Certain directives will spawn a new $scope, which by default inherits from its wrapping $scope using JavaScript prototypical inheritance. The $scope object is accessible in the controller and the view.
This is the clever part. Because the structure of $scope inheritance roughly follows the structure of the DOM, elements have access to their own scope, and any containing scopes seamlessly, all the way up to the global $scope (which is not the same as the global scope).
This makes it much easier to pass data around, and to store data at an appropriate level. If a dropdown is unfolded, only the dropdown $scope needs to know about it. If the user updates their preferences, you might want to update the global $scope, and any nested scopes listening to the user preferences would automatically be alerted.
This might sound complicated, in fact, once you relax into it, it's like flying. You don't need to create the $scope object, AngularJS instantiates and configures it for you, correctly and appropriately based on your template hierarchy. AngularJS then makes it available to your component using the magic of dependency injection (more on this later).
Manual DOM changes vs. Data Binding
In jQuery you make all your DOM changes by hand. You construct new DOM elements programatically. If you have a JSON array and you want to put it to the DOM, you must write a function to generate the HTML and insert it.
In AngularJS you can do this too, but you are encouraged to make use of data binding. Change your model, and because the DOM is bound to it via a template your DOM will automatically update, no intervention required.
Because data binding is done from the template, using either an attribute or the curly brace syntax, it's super easy to do. There's little cognitive overhead associated with it so you'll find yourself doing it all the time.
<input ng-model="user.name" />
Binds the input element to $scope.user.name. Updating the input will update the value in your current scope, and vice-versa.
Likewise:
<p>
{{user.name}}
</p>
will output the user name in a paragraph. It's a live binding, so if the $scope.user.name value is updated, the template will update too.
Ajax all of the time
In jQuery making an Ajax call is fairly simple, but it's still something you might think twice about. There's the added complexity to think about, and a fair chunk of script to maintain.
In AngularJS, Ajax is your default go-to solution and it happens all the time, almost without you noticing. You can include templates with ng-include. You can apply a template with the simplest custom directive. You can wrap an Ajax call in a service and create yourself a GitHub service, or a Flickr service, which you can access with astonishing ease.
Service Objects vs Helper Functions
In jQuery, if we want to accomplish a small non-dom related task such as pulling a feed from an API, we might write a little function to do that in our closure. That's a valid solution, but what if we want to access that feed often? What if we want to reuse that code in another application?
AngularJS gives us service objects.
Services are simple objects that contain functions and data. They are always singletons, meaning there can never be more than one of them. Say we want to access the Stack Overflow API, we might write a StackOverflowService which defines methods for doing so.
Let's say we have a shopping cart. We might define a ShoppingCartService which maintains our cart and contains methods for adding and removing items. Because the service is a singleton, and is shared by all other components, any object that needs to can write to the shopping cart and pull data from it. It's always the same cart.
Service objects are self-contained AngularJS components which we can use and reuse as we see fit. They are simple JSON objects containing functions and Data. They are always singletons, so if you store data on a service in one place, you can get that data out somewhere else just by requesting the same service.
Dependency injection (DI) vs. Instatiation - aka de-spaghettification
AngularJS manages your dependencies for you. If you want an object, simply refer to it and AngularJS will get it for you.
Until you start to use this, it's hard to explain just what a massive time boon this is. Nothing like AngularJS DI exists inside jQuery.
DI means that instead of writing your application and wiring it together, you instead define a library of components, each identified by a string.
Say I have a component called 'FlickrService' which defines methods for pulling JSON feeds from Flickr. Now, if I want to write a controller that can access Flickr, I just need to refer to the 'FlickrService' by name when I declare the controller. AngularJS will take care of instantiating the component and making it available to my controller.
For example, here I define a service:
myApp.service('FlickrService', function() {
return {
getFeed: function() { // do something here }
}
});
Now when I want to use that service I just refer to it by name like this:
myApp.controller('myController', ['FlickrService', function(FlickrService) {
FlickrService.getFeed()
}]);
AngularJS will recognise that a FlickrService object is needed to instantiate the controller, and will provide one for us.
This makes wiring things together very easy, and pretty much eliminates any tendency towards spagettification. We have a flat list of components, and AngularJS hands them to us one by one as and when we need them.
Modular service architecture
jQuery says very little about how you should organise your code. AngularJS has opinions.
AngularJS gives you modules into which you can place your code. If you're writing a script that talks to Flickr for example, you might want to create a Flickr module to wrap all your Flickr related functions in. Modules can include other modules (DI). Your main application is usually a module, and this should include all the other modules your application will depend on.
You get simple code reuse, if you want to write another application based on Flickr, you can just include the Flickr module and voila, you have access to all your Flickr related functions in your new application.
Modules contain AngularJS components. When we include a module, all the components in that module become available to us as a simple list identified by their unique strings. We can then inject those components into each other using AngularJS's dependency injection mechanism.
To sum up
AngularJS and jQuery are not enemies. It's possible to use jQuery within AngularJS very nicely. If you're using AngularJS well (templates, data-binding, $scope, directives, etc.) you will find you need a lot less jQuery than you might otherwise require.
The main thing to realise is that your template drives your application. Stop trying to write big plugins that do everything. Instead write little directives that do one thing, then write a simple template to wire them together.
Think less about unobtrusive JavaScript, and instead think in terms of HTML extensions.
My little book
I got so excited about AngularJS, I wrote a short book on it which you're very welcome to read online http://nicholasjohnson.com/angular-book/. I hope it's helpful.
Can you describe the paradigm shift that is necessary?
Imperative vs Declarative
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.
How do I architect and design client-side web apps differently?
AngularJS is an entire client-side framework that uses the MVC pattern (check out their graphical representation). It greatly focuses on separation of concerns.
What is the biggest difference? What should I stop doing/using; what should I start doing/using instead?
jQuery is a library
AngularJS is a beautiful client-side framework, highly testable, that combines tons of cool stuff such as MVC, dependency injection, data binding and much more.
It focuses on separation of concerns and testing (unit testing and end-to-end testing), which facilitates test-driven development.
The best way to start is going through their awesome tutorial. You can go through the steps in a couple of hours; however, in case you want to master the concepts behind the scenes, they include a myriad of reference for further reading.
Are there any server-side considerations/restrictions?
You may use it on existing applications where you are already using pure jQuery. However, if you want to fully take advantage of the AngularJS features you may consider coding the server side using a RESTful approach.
Doing so will allow you to leverage their resource factory, which creates an abstraction of your server side RESTful API and makes server-side calls (get, save, delete, etc.) incredibly easy.
To describe the "paradigm shift", I think a short answer can suffice.
AngularJS changes the way you find elements
In jQuery, you typically use selectors to find elements, and then wire them up:
$('#id .class').click(doStuff);
In AngularJS, you use directives to mark the elements directly, to wire them up:
<a ng-click="doStuff()">
AngularJS doesn't need (or want) you to find elements using selectors - the primary difference between AngularJS's jqLite versus full-blown jQuery is that jqLite does not support selectors.
So when people say "don't include jQuery at all", it's mainly because they don't want you to use selectors; they want you to learn to use directives instead. Direct, not select!
jQuery
jQuery makes ridiculously long JavaScript commands like getElementByHerpDerp shorter and cross-browser.
AngularJS
AngularJS allows you to make your own HTML tags/attributes that do things which work well with dynamic web applications (since HTML was designed for static pages).
Edit:
Saying "I have a jQuery background how do I think in AngularJS?" is like saying "I have an HTML background how do I think in JavaScript?" The fact that you're asking the question shows you most likely don't understand the fundamental purposes of these two resources. This is why I chose to answer the question by simply pointing out the fundamental difference rather than going through the list saying "AngularJS makes use of directives whereas jQuery uses CSS selectors to make a jQuery object which does this and that etc....". This question does not require a lengthy answer.
jQuery is a way to make programming JavaScript in the browser easier. Shorter, cross-browser commands, etc.
AngularJS extends HTML, so you don't have to put <div> all over the place just to make an application. It makes HTML actually work for applications rather than what it was designed for, which is static, educational web pages. It accomplishes this in a roundabout way using JavaScript, but fundamentally it is an extension of HTML, not JavaScript.
jQuery: you think a lot about 'QUERYing the DOM' for DOM elements and doing something.
AngularJS: THE model is the truth, and you always think from that ANGLE.
For example, when you get data from THE server which you intend to display in some format in the DOM, in jQuery, you need to '1. FIND' where in the DOM you want to place this data, the '2. UPDATE/APPEND' it there by creating a new node or just setting its innerHTML. Then when you want to update this view, you then '3. FIND' the location and '4. UPDATE'. This cycle of find and update all done within the same context of getting and formatting data from server is gone in AngularJS.
With AngularJS you have your model (JavaScript objects you are already used to) and the value of the model tells you about the model (obviously) and about the view, and an operation on the model automatically propagates to the view, so you don't have to think about it. You will find yourself in AngularJS no longer finding things in the DOM.
To put in another way, in jQuery, you need to think about CSS selectors, that is, where is the div or td that has a class or attribute, etc., so that I can get their HTML or color or value, but in AngularJS, you will find yourself thinking like this: what model am I dealing with, I will set the model's value to true. You are not bothering yourself of whether the view reflecting this value is a checked box or resides in a td element (details you would have often needed to think about in jQuery).
And with DOM manipulation in AngularJS, you find yourself adding directives and filters, which you can think of as valid HTML extensions.
One more thing you will experience in AngularJS: in jQuery you call the jQuery functions a lot, in AngularJS, AngularJS will call your functions, so AngularJS will 'tell you how to do things', but the benefits are worth it, so learning AngularJS usually means learning what AngularJS wants or the way AngularJS requires that you present your functions and it will call it accordingly. This is one of the things that makes AngularJS a framework rather than a library.
Those are some very nice, but lengthy answers.
To sum up my experiences:
Controllers and providers (services, factories, etc.) are for modifying the data model, NOT HTML.
HTML and directives define the layout and binding to the model.
If you need to share data between controllers, create a service or factory - they are singletons that are shared across the application.
If you need an HTML widget, create a directive.
If you have some data and are now trying to update HTML... STOP! update the model, and make sure your HTML is bound to the model.
jQuery is a DOM manipulation library.
AngularJS is an MV* framework.
In fact, AngularJS is one of the few JavaScript MV* frameworks (many JavaScript MVC tools still fall under the category library).
Being a framework, it hosts your code and takes ownership of decisions about what to call and when!
AngularJS itself includes a jQuery-lite edition within it. So for some basic DOM selection/manipulation, you really don't have to include the jQuery library (it saves many bytes to run on the network.)
AngularJS has the concept of "Directives" for DOM manipulation and designing reusable UI components, so you should use it whenever you feel the need of doing DOM manipulation related stuff (directives are only place where you should write jQuery code while using AngularJS).
AngularJS involves some learning curve (more than jQuery :-).
-->For any developer coming from jQuery background, my first advice would be to "learn JavaScript as a first class language before jumping onto a rich framework like AngularJS!"
I learned the above fact the hard way.
Good luck.
They're apples and oranges. You don't want to compare them. They're two different things. AngularJs has already jQuery lite built in which allows you to perform basic DOM manipulation without even including the full blown jQuery version.
jQuery is all about DOM manipulation. It solves all the cross browser pain otherwise you will have to deal with but it's not a framework that allows you to divide your app into components like AngularJS.
A nice thing about AngularJs is that it allows you to separate/isolate the DOM manipulation in the directives. There are built-in directives ready for you to use such as ng-click. You can create your own custom directives that will contain all your view logic or DOM manipulation so you don't end up mingle DOM manipulation code in the controllers or services that should take care of the business logic.
Angular breaks down your app into
- Controllers
- Services
- Views
- etc.
and there is one more thing, that's the directive. It's an attribute you can attach to any DOM element and you can go nuts with jQuery within it without worrying about your jQuery ever conflicts with AngularJs components or messes up with its architecture.
I heard from a meetup I attended, one of the founders of Angular said they worked really hard to separate out the DOM manipulation so do not try to include them back in.
Listen to the podcast JavaScript Jabber: Episode #32 that features the original creators of AngularJS: Misko Hevery & Igor Minar. They talk a lot about what it's like to come to AngularJS from other JavaScript backgrounds, especially jQuery.
One of the points made in the podcast made a lot of things click for me with respects to your question:
MISKO: [...] one of the things we thought about very hardly in Angular is, how do we provide lots of escape hatches so that you can get out and basically figure out a way out of this. So to us, the answer is this thing called “Directives”. And with directives, you essentially become a regular little jQuery JavaScript, you can do whatever you want.
IGOR: So think of directive as the instruction to the compiler that tells it whenever you come across this certain element or this CSS in the template, and you keep this kind of code and that code is in charge of the element and everything below that element in the DOM tree.
A transcript of the entire episode is available at the link provided above.
So, to directly answer your question: AngularJS is -very- opinionated and is a true MV* framework. However, you can still do all of the really cool stuff you know and love with jQuery inside of directives. It's not a matter of "How do I do what I used to in jQuery?" as much as it's a matter of "How do I supplement AngularJS with all of the stuff I used to do in jQuery?"
It's really two very different states of mind.
I find this question interesting, because my first serious exposure to JavaScript programming was Node.js and AngularJS. I never learned jQuery, and I guess that's a good thing, because I don't have to unlearn anything. In fact, I actively avoid jQuery solutions to my problems, and instead, solely look for an "AngularJS way" to solve them. So, I guess my answer to this question would essentially boil down to, "think like someone who never learned jQuery" and avoid any temptation to incorporate jQuery directly (obviously AngularJS uses it to some extent behind the scenes).
AngularJS and jQuery:
AngularJs and JQuery are completely different at every level except the JQLite functionality and you will see it once you start learning the AngularJs core features (I explained it below).
AngularJs is a client side framework that offers to build the independent client side application. JQuery is a client side library that play around the DOM.
AngularJs Cool Principle - If you want some changes on your UI think from model data change perspective. Change your data and UI will re-render itself. You need not to play around DOM each time unless and until it is hardly required and that should also be handled through Angular Directives.
To answer this question, I want to share my experience on the first enterprise application with AngularJS. These are the most awesome features that Angular provide where we start changing our jQuery mindset and we get the Angular like a framework and not the library.
Two-way data binding is amazing:
I had a grid with all functionality UPDATE, DELTE, INSERT. I have a data object that binds the grid's model using ng-repeat. You only need to write a single line of simple JavaScript code for delete and insert and that's it. grid automatically updates as the grid model changes instantly. Update functionality is real time, no code for it.
You feel amazing!!!
Reusable directives are super:
Write directives in one place and use it throughout the application. OMG!!! I used these directive for paging, regex, validations, etc. It is really cool!
Routing is strong:
It's up to your implementation how you want to use it, but it requires very few lines of code to route the request to specify HTML and controller (JavaScript)
Controllers are great:
Controllers take care of their own HTML, but this separation works well for common functionality well as. If you want to call the same function on the click of a button on master HTML, just write the same function name in each controller and write individual code.
Plugins:
There are many other similar features like showing an overlay in your app. You don't need to write code for it, just use an overlay plugin available as wc-overlay, and this will automatically take care of all XMLHttpRequest (XHR) requests.
Ideal for RESTful architecture:
Being a complete frameworks makes AngularJS great to work with a RESTful architecture. To call REST CRUD APIs is very easier and
Services: Write common codes using services and less code in controllers. Sevices can be used to share common functionalities among the controllers.
Extensibility: Angular has extended the HTML directives using angular directives. Write expressions inside html and evaluate them on runtime. Create your own directives and services and use them in another project without any extra effort.
As a JavaScript MV* beginner and purely focusing on the application architecture (not the server/client-side matters), I would certainly recommend the following resource (which I am surprised wasn't mentioned yet): JavaScript Design Patterns, by Addy Osmani, as an introduction to different JavaScript Design Patterns. The terms used in this answer are taken from the linked document above. I'm not going to repeat what was worded really well in the accepted answer. Instead, this answer links back to the theoretical backgrounds which power AngularJS (and other libraries).
Like me, you will quickly realize that AngularJS (or Ember.js, Durandal, & other MV* frameworks for that matter) is one complex framework assembling many of the different JavaScript design patterns.
I found it easier also, to test (1) native JavaScript code and (2) smaller libraries for each one of these patterns separately before diving into one global framework. This allowed me to better understand which crucial issues a framework adresses (because you are personally faced with the problem).
For example:
JavaScript Object-oriented Programming (this is a Google search link). It is not a library, but certainly a prerequisite to any application programming. It taught me the native implementations of the prototype, constructor, singleton & decorator patterns
jQuery/ Underscore for the facade pattern (like WYSIWYG's for manipulating the DOM)
Prototype.js for the prototype/ constructor/ mixin pattern
RequireJS/ Curl.js for the module pattern/ AMD
KnockoutJS for the observable, publish/subscribe pattern
NB: This list is not complete, nor 'the best libraries'; they just happen to be the libraries I used. These libraries also include more patterns, the ones mentioned are just their main focuses or original intents. If you feel something is missing from this list, please do mention it in the comments, and I will be glad to add it.
Actually, if you're using AngularJS, you don't need jQuery anymore. AngularJS itself has the binding and directive, which is a very good "replacement" for most things you can do with jQuery.
I usually develop mobile applications using AngularJS and Cordova. The ONLY thing from jQuery I needed is the Selector.
By googling, I see that there is a standalone jQuery selector module out there. It's Sizzle.
And I decided to make a tiny code snippet that help me quickly start a website using AngularJS with the power of jQuery Selector (using Sizzle).
I shared my code here: https://github.com/huytd/Sizzular

ExtJS MVC conventions, naming and behavior

Lately (2.x / 3.x) I just used xtype & factory methods to receive a instance of a class which was as simply as fast. Now I have started 4.x and my first App with MVC. As described in the tutorial the MVC pattern requires me to extend a class for each view I wan't to use, even if I use it just one time. But the best practice written by Sencha itself says:
just extend for re-useability or adding of functionality
In my case I need to register a whole bunch of classes even if they could be created from one base class except of some params like title, width,...
Another point is that the Controller overwrites any StoreId by convention and also requires a strict typing, means the class-name must end with an s. But as far as I know I cannot spare neither the model nor the store within the the controller store/model-array so is there any other point for this convention cause it seems not to spare typing.
Next point is that after merging from 3.X to 4.X the application initial load time has extended which seems to be caused due to either the many new classes that need to get defined or due to the fact that all controllers get instantiated at startup due to the default behavior of the MVC pattern. Is there any way to not auto instantiate a controller and just doing it lazy, for example when I request it on the application controller?
Yes I know, that are a bunch of questions but I guess they all around the same topic.
EDIT
After some sourcecode-digging I am no longer sure about the
requirement of the s when naming a store. I thought I stumbled over
this while going through the MVC tutorial. Can anyone verify this?
EDIT 2
My conclusions
Lacy rendering is quite simple. First of all the Controller should not be mentioned in the ApplicationController controller array. To create a instance of such a controller use the ApplicationController.getController(pureClassName)
[Note that each controller contains a reference to the ApplicationController called application] Now you need to be aware of the fact that the init(application) method and the onLaunch(application) method get no longer invoked by the ApplicationController, you need to do this yourself. When calling getController() the ApplicationController first lookup if there is already a instance of this controller in the internal reference cache if not it creates a instance and inject the controllername as Id. So controllers are a sort of singleton which is perfectly fine.
The controller itself creates all the getter for the registered stores, models and views and, that's a guess, it instantiate them (at least the stores)
About naming restrictions for stores, there no restrictions about ending with an s.
These are very valid points.
First, it has to be mentioned that you don't have to use MVC with ExtJS 4. You can still use ExtJS 3 style in your code.
I assume that if you understand the advantages of MVC and decide to adapt it, then yes - you will have to extend classes and there is some overhead, but admittedly you will end up with a cleaner, more reusable code. It has to be said that while you need to extend top-level views, the items within them can still be coded old style. In addition to this, within the init() of the controller you can modify certain view configs (which allows less of class extension, but more controller code).
I have to admit that if you have experience with ExtJS 3 and you're migrating to MVC style of an app, you will eventually see that the benefits outweigh the work involved.
Personally it's the first time I've been made aware of this 's' business with stores. So I can't comment much on this.
Lastly, a properly-written ExtJs 4 app, one that makes use of dynamic loading should load faster than an ExtJS 3 app. You can also compile an Ext version that only includes code used in your app. And yes, you can instantiate controllers (and their views and stores) when you need them, which works like a charm:
loadPage: function(aControllerName)
{
// save recent page in a cookie
Ext.util.Cookies.set('RecentPage', aControllerName);
// Dynamically load the controller
var iController = this.getController(aControllerName);
// Manually initialise it
iController.init();
// Load the page (by getting the first view of the controller).
var iPage = this.getView(iController.views[0]).create();
// Add the page to the content panel.
var iContentPanel = this.getContentPanel();
iContentPanel.removeAll(true);
iContentPanel.add(iPage);
iContentPanel.doLayout();
}
1.Izhaki answered your question well about the lazy controller initialization.
2.I am not really following you on the gripe about Store names. There are no restrictions on store names. They are merely suggestions of naming conventions.
3.The Ext.define method is great to define your classes - similar to Java or other OO languages. This is NOT required however and you can simply use Ext.create method to create an instance of a framework component and pass it custom config object.
You can also use Ext.define to create you base class and then call Ext.create('MyBaseClass',{title:'mynew tile'}); to get a slightly modified version of your base class.
I encourage you to read through the Sencha guides on MVC, and Class system and also review their examples to get better understanding.

Categories

Resources