“Navigation between pages was straightforward in the early days of the web. One could type a URL in the browser’s address bar to retrieve a precisely identified resource. After all, a URL is used to point to a single, physical resource (a file) on a server. When a page was loaded, we could follow hyperlinks to jump between resources as well as use the browser’s back and forward buttons to move between visited items. The rise of dynamically rendered pages broke this simple navigation paradigm. All of a sudden, the same URL could result in different pages being sent to a browser, depending on the application’s internal state. The back and forward buttons were the first victims of the highly interactive web. Their usage became unpredictable, and many websites are still going as far as discouraging the use of the back and forward navigation buttons (encouraging users to rely on internal navigation links). Single-page web applications didn’t improve the situation, far from it! In modern, AJAX-heavy applications, it is not uncommon to see only a single URL in the browser’s address bar (the one that was used to initially load the application). Subsequent HTTP interactions happen through the XHR object, without affecting the browser’s address bar. In this setup, the back and forward buttons are completely useless, since pressing them would take us to completely different websites, instead of a place within the current application. Bookmarking or copying and pasting a link from the browser’s address bar is not much use either. A bookmarked link will always point to the starting page of an application. But the browser’s back and forward buttons and ability to bookmark URLs are very useful. Users don’t want to give them up while working with single- page web applications! Fortunately, AngularJS is well-equipped to help us handle URLs with the same efficiency as in the good, olden days of the static resources web!”—URLs in single-page web applications, from Mastering Web Application
Development with AngularJS, by Pawel Kozlowski & Peter Bacon Darwin
Providers are objects that provide (create) instances of services and expose configuration APIs that can be used to control the creation and runtime behavior of a service. In case of the $route service, the $routeProvider exposes APIs that allow you to define routes for your application.
Note: Providers can only be injected into config functions. Thus you could not inject $routeProvider into PhoneListCtrl.
“The sole responsibilities of the injector are to load specified module definition(s), register all service providers defined in these modules, and when asked, inject a specified function with dependencies (services) that it lazily instantiates via their providers.”—http://docs.angularjs.org/tutorial/step_07
Compiler: Compile, link, tranclude and directive in AngularJS
Compiler is an Angular service which traverses the DOM looking for attributes. The compilation process happens in two phases.
Compile: traverse the DOM and collect all of the directives. The result is a linking function.
Link: combine the directives with a scope and produce a live view. Any changes in the scope model are reflected in the view, and any user interactions with the view are reflected in the scope model. This makes the scope model the single source of truth.
A directive is just a function which executes when the compiler encounters it in the DOM.
How directives are compiled
The difference between Compile and Link in directive
Directives often have a link function. But it’s rare for directives to have a compile function, since most directives are concerned with working with a specific DOM element instance rather than changing its overall structure.
Transclusion in directive
When declaring a directive, use ngTransclude in template together with the tranclude: true option to enable transclusion. The contents of a transcluded directive have whatever scope is outside the directive. So it’s not affected by the isolated scope of the directive itself.
And it states very clear why isolated scope and transclude scope of a directive are siblings:
This behavior makes sense for a directive that wraps some content, because otherwise you’d have to pass in each model you wanted to use separately. If you have to pass in each model that you want to use, then you can’t really have arbitrary contents, can you?
There are two demos that demonstrate how transclusion and compile function may be used in a directive in this blog post.
The goal behind the expressions that you use in templates is to let you be as clever as you need to be to create hooks between your template, your application logic, and your data, but at the same time prevent application logic from sneaking into the template.
Controllers have three responsibilities in your app:
Set up the initial state in your application’s model
Expose model and functions to the view (UI template) through $scope
Watch other parts of the model for changes and take action
Note the difference between the extra parameters passed here and the eventData parameter to the .on() method. Both are mechanisms for passing information to an event handler, but the extraParameters argument to .trigger() allows information to be determined at the time the event is triggered, while the eventData argument to .on() requires the information to be already computed at the time the handler is bound.