From c213c93c51fb95d7fb831944a8e56de70b8f50f5 Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Mon, 16 Mar 2015 14:44:53 -0700 Subject: [PATCH 01/19] Initial commit --- .gitignore | 1 - LICENSE | 21 - README.html | 857 +++++++++++++ README.md | 1089 ----------------- images/active-record.svg => active-record.svg | 0 assets/DroidSans.woff | Bin 0 -> 26348 bytes assets/assert.css | 10 + assets/hljs-github.min.css | 124 ++ assets/jquery-1.6.1.min.js | 18 + assets/prettify.css | 52 + assets/prettify.js | 28 + assets/runner.js | 35 + assets/style.css | 273 +++++ assets/sunburst.css | 53 + build/AngularJS in Patterns.pdf | Bin 702440 -> 0 bytes ...ities.svg => chain-of-responsibilities.svg | 0 images/command.svg => command.svg | 0 images/composite.svg => composite.svg | 0 images/data-mapper.svg => data-mapper.svg | 0 images/decorator.svg => decorator.svg | 0 images/facade.svg => facade.svg | 0 .../factory-method.svg => factory-method.svg | 0 gulpfile.js | 12 - ...ng-filters.svg => intercepting-filters.svg | 0 images/interpreter.svg => interpreter.svg | 0 images/observer.svg => observer.svg | 0 package.json | 22 - ...page-controller.svg => page-controller.svg | 0 images/proxy.svg => proxy.svg | 0 images/singleton.svg => singleton.svg | 0 images/template-view.svg => template-view.svg | 0 31 files changed, 1450 insertions(+), 1145 deletions(-) delete mode 100644 .gitignore delete mode 100644 LICENSE create mode 100644 README.html delete mode 100644 README.md rename images/active-record.svg => active-record.svg (100%) create mode 100644 assets/DroidSans.woff create mode 100644 assets/assert.css create mode 100644 assets/hljs-github.min.css create mode 100644 assets/jquery-1.6.1.min.js create mode 100644 assets/prettify.css create mode 100644 assets/prettify.js create mode 100644 assets/runner.js create mode 100644 assets/style.css create mode 100644 assets/sunburst.css delete mode 100644 build/AngularJS in Patterns.pdf rename images/chain-of-responsibilities.svg => chain-of-responsibilities.svg (100%) rename images/command.svg => command.svg (100%) rename images/composite.svg => composite.svg (100%) rename images/data-mapper.svg => data-mapper.svg (100%) rename images/decorator.svg => decorator.svg (100%) rename images/facade.svg => facade.svg (100%) rename images/factory-method.svg => factory-method.svg (100%) delete mode 100644 gulpfile.js rename images/intercepting-filters.svg => intercepting-filters.svg (100%) rename images/interpreter.svg => interpreter.svg (100%) rename images/observer.svg => observer.svg (100%) delete mode 100644 package.json rename images/page-controller.svg => page-controller.svg (100%) rename images/proxy.svg => proxy.svg (100%) rename images/singleton.svg => singleton.svg (100%) rename images/template-view.svg => template-view.svg (100%) diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0a0af45..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/README.pdf \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index dcd4ce7..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Minko Gechev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/README.html b/README.html new file mode 100644 index 0000000..5c0f1d3 --- /dev/null +++ b/README.html @@ -0,0 +1,857 @@ +<!DOCTYPE html> +<html> + <head> + <title>AngularJS in Patterns</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <style type="text/css"> + @font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: normal; + src: local('Droid Sans'), local('DroidSans'), url('DroidSans.woff') format('woff'); + } + </style> + <link href='http://fonts.googleapis.com/css?family=Andika|Cantarell:400,700,400italic' rel='stylesheet' type='text/css' /> + <link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css' /> + <script src="assets/jquery-1.6.1.min.js"></script> + <link type="text/css" rel="stylesheet" href="assets/style.css"/> + <link type="text/css" rel="stylesheet" href="assets/assert.css"/> + <link type="text/css" rel="stylesheet" href="assets/prettify.css"/> + <link type="text/css" rel="stylesheet" href="assets/hljs-github.min.css"/> + + <script type="text/javascript" src="assets/prettify.js"></script> + <!-- Script runner --> + <script type="text/javascript" src="assets/runner.js"></script> + </head> +<body> + <div id="wrapper"> + <div id="header"> + </div> + <div class="clear"> + <hr> + </div> + + <!-- Main --> + + <div id="main"> + <div id="container"> + <div id="content" class="post"><h1 id="angularjs-in-patterns">AngularJS in Patterns</h1> +<h2 id="table-of-contents">Table of Contents</h2> +<ul class="list"> +<li><a href="#abstract">Abstract</a></li> +<li><a href="#introduction">Introduction</a></li> +<li><a href="#angularjs-overview">AngularJS overview</a></li> +<li><a href="#partials">Partials</a></li> +<li><a href="#controllers">Controllers</a></li> +<li><a href="#scope">Scope</a></li> +<li><a href="#directives">Directives</a></li> +<li><a href="#filters">Filters</a></li> +<li><a href="#services">Services</a></li> +<li><a href="#angularjs-patterns">AngularJS Patterns</a></li> +<li><a href="#services-1">Services</a><ul class="list"> +<li><a href="#singleton">Singleton</a></li> +<li><a href="#factory-method">Factory Method</a></li> +<li><a href="#decorator">Decorator</a></li> +<li><a href="#facade">Facade</a></li> +<li><a href="#proxy">Proxy</a></li> +<li><a href="#active-record">Active Record</a></li> +<li><a href="#intercepting-filters">Intercepting Filters</a></li> +</ul> +</li> +<li><a href="#directives-1">Directives</a><ul class="list"> +<li><a href="#composite">Composite</a></li> +<li><a href="#interpreter">Interpreter</a></li> +<li><a href="#template-view">Template View</a></li> +</ul> +</li> +<li><a href="#scope-1">Scope</a><ul class="list"> +<li><a href="#observer">Observer</a></li> +<li><a href="#chain-of-responsibilities">Chain of Responsibilities</a></li> +<li><a href="#command">Command</a></li> +</ul> +</li> +<li><a href="#controller-1">Controller</a><ul class="list"> +<li><a href="#page-controller">Page Controller</a></li> +</ul> +</li> +<li><a href="#others">Others</a><ul class="list"> +<li><a href="#module-pattern">Module Pattern</a></li> +<li><a href="#data-mapper">Data Mapper</a></li> +</ul> +</li> +<li><a href="#references">References</a></li> +</ul> +<h2 id="abstract">Abstract</h2> +<p>One of the best ways to learn something new is to see how the things you already know are used in it. +This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. +The goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.</p> +<h2 id="introduction">Introduction</h2> +<p>The document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.</p> +<p>The last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.</p> +<h2 id="angularjs-overview">AngularJS overview</h2> +<p>AngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA). +SPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand. +Since most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:</p> +<ul class="list"> +<li>two-way data binding</li> +<li>dependency injection</li> +<li>separation of concerns</li> +<li>testability</li> +<li>abstraction</li> +</ul> +<p>The separation of concerns is achieved by dividing each AngularJS application into separate components, such as:</p> +<ul class="list"> +<li>partials</li> +<li>controllers</li> +<li>directives</li> +<li>services</li> +<li>filters</li> +</ul> +<p>These components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.</p> +<h3 id="partials">Partials</h3> +<p>The partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).</p> +<p>Initially each SPA loads <code>index.html</code> file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.</p> +<p><strong>Sample partial</strong></p> +<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">html</span> <span class="hljs-attribute">ng-app</span>></span> + <span class="hljs-comment"><!-- Body tag augmented with ngController directive --></span> + <span class="hljs-tag"><<span class="hljs-title">body</span> <span class="hljs-attribute">ng-controller</span>=<span class="hljs-value">"MyController"</span>></span> + <span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">ng-model</span>=<span class="hljs-value">"foo"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"bar"</span>></span> + <span class="hljs-comment"><!-- Button tag with ng-click directive, and + string expression 'buttonText' + wrapped in "</span></span><span class="hljs-expression">{{ }}</span><span class="xml"><span class="hljs-comment">" markup --></span> + <span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">ng-click</span>=<span class="hljs-value">"changeFoo()"</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">buttonText</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">button</span>></span> + <span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"angular.js"</span>></span><span class="javascript"></span><span class="hljs-tag"></<span class="hljs-title">script</span>></span> + <span class="hljs-tag"></<span class="hljs-title">body</span>></span> +<span class="hljs-tag"></<span class="hljs-title">html</span>></span></span></code></pre><p>With AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute <code>ng-click</code> states that the method <code>changeFoo</code> of the current <em>scope</em> will be invoked.</p> +<h3 id="controllers">Controllers</h3> +<p>The AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the <em>scope</em>. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the <em>model</em> to the partials by attaching data to the <em>scope</em>. We can think of this data as <em>view model</em>.</p> +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyController</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-variable">$scope</span>.buttonText = <span class="hljs-string">'Click me to change foo!'</span>; + <span class="hljs-variable">$scope</span>.foo = <span class="hljs-number">42</span>; + + <span class="hljs-variable">$scope</span>.changeFoo = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + <span class="hljs-variable">$scope</span>.foo += <span class="hljs-number">1</span>; + alert(<span class="hljs-string">'Foo changed'</span>); + }; +}</code></pre><p>For example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.</p> +<ol class="list"> +<li>Change the value of <code>foo</code> by typing in the input box. This will immediately reflect the value of <code>foo</code> because of the two-way data binding.</li> +<li>Change the value of <code>foo</code> by clicking the button, which will be labeled <code>Click me to change foo!</code>.</li> +</ol> +<p>All the custom elements, attributes, comments or classes could be recognized as AngularJS <em>directives</em> if they are previously defined as ones.</p> +<h3 id="scope">Scope</h3> +<p>In AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate <em>directives</em>, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.</p> +<p>Another important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as <em>isolated</em>). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.</p> +<p>Scope inheritance is illustrated in the following example:</p> +<pre class="hljs"><code><<span class="hljs-keyword">div</span> ng-controller=<span class="hljs-string">"BaseCtrl"</span>> + <<span class="hljs-keyword">div</span> id=<span class="hljs-string">"child"</span> ng-controller=<span class="hljs-string">"ChildCtrl"</span>> + <button id=<span class="hljs-string">"parent-method"</span> ng-click=<span class="hljs-string">"foo()"</span>><span class="hljs-type">Parent</span> <span class="hljs-keyword">method</span></button> + <button ng-click=<span class="hljs-string">"bar()"</span>><span class="hljs-type">Child</span> <span class="hljs-keyword">method</span></button> + </<span class="hljs-keyword">div</span>> +</<span class="hljs-keyword">div</span>></code></pre><pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BaseCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-variable">$scope</span>.foo = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + alert(<span class="hljs-string">'Base foo'</span>); + }; +} + +<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ChildCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-variable">$scope</span>.bar = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + alert(<span class="hljs-string">'Child bar'</span>); + }; +}</code></pre><p>With <code>div#child</code> is associated <code>ChildCtrl</code> but since the scope injected inside <code>ChildCtrl</code> inherits prototypically from its parent scope (i.e. the one injected inside <code>BaseCtrl</code>) the method <code>foo</code> is accessible by <code>button#parent-method</code>.</p> +<h3 id="directives">Directives</h3> +<p>In AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new direcrive or consider refactoring of already existing one, which could handle the required DOM manipulations. +Each directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of <em>postLink</em> function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:</p> +<ul class="list"> +<li>template</li> +<li>compile function</li> +<li>link function</li> +<li>etc...</li> +</ul> +<p>By citing the name of the directives they can be used inside the declarative partials.</p> +<p>Example:</p> +<pre class="hljs"><code>myModule.directive(<span class="hljs-string">'alertButton'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + <span class="hljs-keyword">return</span> { + template: <span class="hljs-string">'<button ng-transclude></button>'</span>, + scope: { + content: <span class="hljs-string">'@'</span> + }, + replace: <span class="hljs-literal">true</span>, + restrict: <span class="hljs-string">'E'</span>, + transclude: <span class="hljs-literal">true</span>, + link: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(scope, el)</span> </span>{ + el.click(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + alert(scope.content); + }); + } + }; +});</code></pre><pre class="hljs"><code><alert-<span class="hljs-tag">button</span> <span class="hljs-attribute">content</span>=<span class="hljs-string">"42"</span>>Click me</alert-button></code></pre><p>In the example above the tag <code><alert-button></alert-button></code> will be replaced button element. When the user clicks on the button the string <code>42</code> will be alerted.</p> +<p>Since the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.</p> +<h3 id="filters">Filters</h3> +<p>The filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, <em>services</em> and other filters through Dependency Injection.</p> +<p>Here is a definition of a sample filter, which changes the given string to uppercase:</p> +<pre class="hljs"><code>myModule.filter(<span class="hljs-string">'uppercase'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(str)</span> </span>{ + <span class="hljs-keyword">return</span> (str || <span class="hljs-string">''</span>).toUpperCase(); + }; +});</code></pre><p>Inside a partial this filter could be used using the Unix's piping syntax:</p> +<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span></span><span class="hljs-expression">{{ <span class="hljs-variable">name</span> | <span class="hljs-variable">uppercase</span> }}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">div</span>></span></span></code></pre><p>Inside a controller the filter could be used as follows:</p> +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyCtrl</span><span class="hljs-params">(uppercaseFilter)</span> </span>{ + <span class="hljs-variable">$scope</span>.name = uppercaseFilter(<span class="hljs-string">'foo'</span>); <span class="hljs-comment">//FOO</span> +}</code></pre><h3 id="services">Services</h3> +<p>Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service.</p> +<pre class="hljs"><code>myModule.service(<span class="hljs-string">'Developer'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + <span class="hljs-keyword">this</span>.name = <span class="hljs-string">'Foo'</span>; + <span class="hljs-keyword">this</span>.motherLanguage = <span class="hljs-string">'JavaScript'</span>; + <span class="hljs-keyword">this</span>.live = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) { + <span class="hljs-keyword">this</span>.code(); + } + }; +});</code></pre><p>The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).</p> +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyCtrl</span><span class="hljs-params">(developer)</span> </span>{ + <span class="hljs-keyword">var</span> developer = <span class="hljs-keyword">new</span> Developer(); + developer.live(); +}</code></pre><h2 id="angularjs-patterns">AngularJS Patterns</h2> +<p>In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.</p> +<p>In the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.</p> +<h3 id="services">Services</h3> +<h4 id="singleton">Singleton</h4> +<blockquote> +<p>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.</p> +</blockquote> +<p>In the UML diagram bellow is illustrated the singleton design pattern.</p> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/singleton.svg" alt="Singleton" title="Fig. 1"></p> +<p>When given dependency is required by any component, AngularJS resolves it using the following algorithm:</p> +<ul class="list"> +<li>Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).</li> +<li>If the dependency exists AngularJS pass it as parameter to the component, which requires it.</li> +<li>If the dependency does not exists:<ul class="list"> +<li>AngularJS instantiate it by calling the factory method of its provider (i.e. <code>$get</code>). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.</li> +<li>AngularJS caches it inside the hash map mentioned above.</li> +<li>AngularJS passes it as parameter to the component, which requires it.</li> +</ul> +</li> +</ul> +<p>We can take better look at the AngularJS' source code, which implements the method <code>getService</code>:</p> +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getService</span><span class="hljs-params">(serviceName)</span> </span>{ + <span class="hljs-keyword">if</span> (cache.hasOwnProperty(serviceName)) { + <span class="hljs-keyword">if</span> (cache[serviceName] === INSTANTIATING) { + <span class="hljs-keyword">throw</span> $injectorMinErr(<span class="hljs-string">'cdep'</span>, <span class="hljs-string">'Circular dependency found: {0}'</span>, path.join(<span class="hljs-string">' <- '</span>)); + } + <span class="hljs-keyword">return</span> cache[serviceName]; + } <span class="hljs-keyword">else</span> { + <span class="hljs-keyword">try</span> { + path.unshift(serviceName); + cache[serviceName] = INSTANTIATING; + <span class="hljs-keyword">return</span> cache[serviceName] = factory(serviceName); + } <span class="hljs-keyword">catch</span> (err) { + <span class="hljs-keyword">if</span> (cache[serviceName] === INSTANTIATING) { + <span class="hljs-keyword">delete</span> cache[serviceName]; + } + <span class="hljs-keyword">throw</span> err; + } <span class="hljs-keyword">finally</span> { + path.shift(); + } + } +}</code></pre><p>We can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as <code>cache</code>).</p> +<p>This way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:</p> +<ul class="list"> +<li>It improves the testability of your source code</li> +<li>You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)</li> +</ul> +<p>For further discussion on this topic Misko Hevery's <a href="http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html">article</a> in the Google Testing blog could be considered.</p> +<h4 id="factory-method">Factory Method</h4> +<blockquote> +<p>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/factory-method.svg" alt="Factory Method" title="Fig. 2"></p> +<p>Lets consider the following snippet:</p> +<pre class="hljs"><code>myModule.config(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$provide</span>)</span> </span>{ + <span class="hljs-variable">$provide</span>.provider(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + <span class="hljs-keyword">var</span> baz = <span class="hljs-number">42</span>; + <span class="hljs-keyword">return</span> { + <span class="hljs-comment">//Factory method</span> + <span class="hljs-variable">$get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(bar)</span> </span>{ + <span class="hljs-keyword">var</span> baz = bar.baz(); + <span class="hljs-keyword">return</span> { + baz: baz + }; + } + }; + }); +});</code></pre><p>In the code above we use the <code>config</code> callback in order to define new "provider". Provider is an object, which has a method called <code>$get</code>. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.</p> +<p>Each service, filter, directive and controller has a provider (i.e. object which factory method, called <code>$get</code>), which is responsible for creating the component's instance.</p> +<p>We can dig a little bit deeper in AngularJS' implementation:</p> +<pre class="hljs"><code>//<span class="hljs-keyword">...</span> + +createInternalInjector(instanceCache, <span class="hljs-keyword">function</span>(servicename) { + var provider = providerInjector.get(servicename + providerSuffix); + <span class="hljs-keyword">return</span> instanceInjector.invoke(provider.$get, provider, undefined, servicename); +}, strictDi)); + +//<span class="hljs-keyword">...</span> + +<span class="hljs-keyword">function</span> invoke(fn, self, locals, serviceName){ + <span class="hljs-keyword">if</span> (typeof locals === <span class="hljs-string">'string'</span>) { + serviceName = locals; + locals = null; + } + + var args = [], + $inject = annotate(fn, strictDi, serviceName), + length, i, + key; + + <span class="hljs-keyword">for</span>(i = <span class="hljs-number">0</span>, length = $inject.length; i < length; i++) { + key = $inject[i]; + <span class="hljs-keyword">if</span> (typeof key !== <span class="hljs-string">'string'</span>) { + throw $injectorMinErr(<span class="hljs-string">'itkn'</span>, + <span class="hljs-string">'Incorrect injection token! Expected service name as string, got {0}'</span>, key); + } + args.push( + locals && locals.hasOwnProperty(key) + ? locals[key] + : getService(key) + ); + } + <span class="hljs-keyword">if</span> (!fn.$inject) { + // this means that we must be an array. + fn = fn[length]; + } + + <span class="hljs-keyword">return</span> fn.apply(self, args); +}</code></pre><p>From the example above we can notice how the <code>$get</code> method is actually used:</p> +<pre class="hljs"><code>instanceInjector.<span class="hljs-function"><span class="hljs-title">invoke</span><span class="hljs-params">(provider.<span class="hljs-variable">$get</span>, provider, undefined, servicename)</span></span></code></pre><p>The snippet above calls the <code>invoke</code> method of <code>instanceInjector</code> with the factory method (i.e. <code>$get</code>) of given service, as first argument. Inside <code>invoke</code>'s body <code>annotate</code> is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: <code>fn.apply(self, args)</code>.</p> +<p>If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product".</p> +<p>There are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:</p> +<ul class="list"> +<li>The most appropriate moment, when the component needs to be instantiated</li> +<li>Resolving all the dependencies required by the component</li> +<li>The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)</li> +</ul> +<h4 id="decorator">Decorator</h4> +<blockquote> +<p>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/decorator.svg" alt="Decorator" title="Fig. 4"></p> +<p>AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method <code>decorator</code> of <code>$provide</code> you can create "wrapper" of any service you have previously defined or used by a third-party:</p> +<pre class="hljs"><code>myModule.controller(<span class="hljs-string">'MainCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(foo)</span> </span>{ + foo.bar(); +}); + +myModule.factory(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + <span class="hljs-keyword">return</span> { + bar: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + console.log(<span class="hljs-string">'I\'m bar'</span>); + }, + baz: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + console.log(<span class="hljs-string">'I\'m baz'</span>); + } + }; +}); + +myModule.config(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$provide</span>)</span> </span>{ + <span class="hljs-variable">$provide</span>.decorator(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$delegate</span>)</span> </span>{ + <span class="hljs-keyword">var</span> barBackup = <span class="hljs-variable">$delegate</span>.bar; + <span class="hljs-variable">$delegate</span>.bar = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + console.log(<span class="hljs-string">'Decorated'</span>); + barBackup.apply(<span class="hljs-variable">$delegate</span>, arguments); + }; + <span class="hljs-keyword">return</span> <span class="hljs-variable">$delegate</span>; + }); +});</code></pre><p>The example above defines new service called <code>foo</code>. In the <code>config</code> callback is called the method <code>$provide.decorator</code> with first argument <code>"foo"</code>, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. <code>$delegate</code> keeps reference to the original service <code>foo</code>. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function. +We decorate the service by overriding its method <code>bar</code>. The actual decoration is simply extending <code>bar</code> by invoking one more <code>console.log statement</code> - <code>console.log('Decorated');</code> and after that call the original <code>bar</code> method with the appropriate context.</p> +<p>Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">aspect-oriented programming</a>. The only AOP framework for AngularJS I'm aware of could be found at <a href="https://github.com/mgechev/angular-aop">github.com/mgechev/angular-aop</a>.</p> +<h4 id="facade">Facade</h4> +<blockquote> +<p>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:</p> +<ol class="list"> +<li><p>make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;</p> +</li> +<li><p>make the library more readable, for the same reason;</p> +</li> +<li><p>reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;</p> +</li> +<li><p>wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).</p> +</li> +</ol> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/facade.svg" alt="Facade" title="Fig. 11"></p> +<p>There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.</p> +<p>For example, lets take a look how we can create an <code>XMLHttpRequest</code> POST request:</p> +<pre class="hljs"><code>var <span class="hljs-keyword">http</span> = new XMLHttpRequest(), + url = <span class="hljs-string">'/example/new'</span>, + params = encodeURIComponent(data); +<span class="hljs-keyword">http</span>.<span class="hljs-keyword">open</span>(<span class="hljs-string">"POST"</span>, url, true); + +<span class="hljs-keyword">http</span>.setRequestHeader(<span class="hljs-string">"Content-type"</span>, <span class="hljs-string">"application/x-www-form-urlencoded"</span>); +<span class="hljs-keyword">http</span>.setRequestHeader(<span class="hljs-string">"Content-length"</span>, params.length); +<span class="hljs-keyword">http</span>.setRequestHeader(<span class="hljs-string">"Connection"</span>, <span class="hljs-string">"close"</span>); + +<span class="hljs-keyword">http</span>.onreadystatechange = function () { + <span class="hljs-keyword">if</span>(<span class="hljs-keyword">http</span>.readyState == <span class="hljs-number">4</span> && <span class="hljs-keyword">http</span>.status == <span class="hljs-number">200</span>) { + alert(<span class="hljs-keyword">http</span>.responseText); + } +} +<span class="hljs-keyword">http</span>.send(params);</code></pre><p>But if we want to post this data using the AngularJS' <code>$http</code> service we can:</p> +<pre class="hljs"><code>$http({ + <span class="hljs-keyword">method</span>: '<span class="hljs-type">POST</span>', + url: '/example/new', + data: data +}) +.then(function (response) { + alert(response); +});</code></pre><p>or we can even:</p> +<pre class="hljs"><code>$http.post(<span class="hljs-string">'/someUrl'</span>, data) +.<span class="hljs-keyword">then</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(response)</span></span> { + alert(response); +});</code></pre><p>The second option provides pre-configured version, which creates a HTTP POST request to the given URL.</p> +<p>Even higher level of abstraction is being created by <code>$resource</code>, which is build over the <code>$http</code> service. We will take a further look at this service in <a href="#active-record">Active Record</a> and <a href="#proxy">Proxy</a> sections.</p> +<h4 id="proxy">Proxy</h4> +<blockquote> +<p>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/proxy.svg" alt="Proxy" title="Fig. 9"></p> +<p>We can distinguish three different types of proxy:</p> +<ul class="list"> +<li>Virtual Proxy</li> +<li>Remote Proxy</li> +<li>Protection Proxy</li> +</ul> +<p>In this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.</p> +<p>In the snippet bellow, there is a call to the <code>get</code> method of <code>$resource</code> instance, called <code>User</code>:</p> +<pre class="hljs"><code><span class="hljs-built_in">var</span> User <span class="hljs-subst">=</span> <span class="hljs-variable">$resource</span>(<span class="hljs-string">'/users/:id'</span>), + user <span class="hljs-subst">=</span> User<span class="hljs-built_in">.</span>get({ id: <span class="hljs-number">42</span> }); +console<span class="hljs-built_in">.</span><span class="hljs-keyword">log</span>(user); <span class="hljs-comment">//{}</span></code></pre><p><code>console.log</code> would outputs an empty object. Since the AJAX request, which happens behind the scene, when <code>User.get</code> is invoked, is asynchronous, we don't have the actual user when <code>console.log</code> is called. Just after <code>User.get</code> makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.</p> +<p>How does this works with AngularJS? Well, lets consider the following snippet:</p> +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MainCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, <span class="hljs-variable">$resource</span>)</span> </span>{ + <span class="hljs-keyword">var</span> User = <span class="hljs-variable">$resource</span>(<span class="hljs-string">'/users/:id'</span>), + <span class="hljs-variable">$scope</span>.user = User.get({ id: <span class="hljs-number">42</span> }); +}</code></pre><pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">span</span> <span class="hljs-attribute">ng-bind</span>=<span class="hljs-value">"user.name"</span>></span><span class="hljs-tag"></<span class="hljs-title">span</span>></span></code></pre><p>Initially when the snippet above executes, the property <code>user</code> of the <code>$scope</code> object will be with value an empty object (<code>{}</code>), which means that <code>user.name</code> will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next <code>$digest</code> loop AngularJS will detect change in <code>$scope.user</code>, which will lead to update of the view.</p> +<h4 id="active-record">Active Record</h4> +<blockquote> +<p>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/active-record.svg" alt="Active Record" title="Fig. 7"></p> +<p>AngularJS defines a service called <code>$resource</code>. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.</p> +<p>According to the AngularJS' documentation <code>$resource</code> is:</p> +<blockquote> +<p>A factory which creates a resource object that lets you interact with RESTful server-side data sources. +The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.</p> +</blockquote> +<p>Here is how <code>$resource</code> could be used:</p> +<pre class="hljs"><code><span class="hljs-built_in">var</span> User <span class="hljs-subst">=</span> <span class="hljs-variable">$resource</span>(<span class="hljs-string">'/users/:id'</span>), + user <span class="hljs-subst">=</span> <span class="hljs-literal">new</span> User({ + name: <span class="hljs-string">'foo'</span>, + age : <span class="hljs-number">42</span> + }); + +user<span class="hljs-built_in">.</span><span class="hljs-variable">$save</span>();</code></pre><p>The call of <code>$resource</code> will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.</p> +<p>This way we can use the constructor function and its static methods by:</p> +<pre class="hljs"><code><span class="hljs-tag">User</span><span class="hljs-class">.get</span>({ <span class="hljs-attribute">userid</span>: userid });</code></pre><p>The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see <a href="#proxy">proxy</a>).</p> +<p>You can find more details for <code>$resource</code> <a href="http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/">The magic of $resource</a> and <a href="https://docs.angularjs.org/api/ngResource/service/$resource">AngularJS' documentation</a>.</p> +<p>Since Martin Fowler states that</p> +<blockquote> +<p>responsibility of the Active Record object is to take care of the communication with the databse in order to create...</p> +</blockquote> +<p><code>$resource</code> does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as "Active Record like RESTful communication".</p> +<h4 id="intercepting-filters">Intercepting Filters</h4> +<blockquote> +<p>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/intercepting-filters.svg" alt="Composite" title="Fig. 3"></p> +<p>In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.</p> +<p>In AngularJS we have the idea of the Intercepting Filters in <code>$httpProvider</code>. <code>$httpProvider</code> has an array property called <code>interceptors</code>, which contains a list of objects. Each object may have properties called: <code>request</code>, <code>response</code>, <code>requestError</code>, <code>responseError</code>.</p> +<p><code>requestError</code> is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively <code>responseError</code> is being called when the previous <code>response</code> interceptor has thrown an error.</p> +<p>Here is a basic example how you can add interceptors using object literal:</p> +<pre class="hljs"><code><span class="hljs-variable">$httpProvider</span>.interceptors.push(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(<span class="hljs-variable">$q</span>, dependency1, dependency2)</span> </span>{ + <span class="hljs-keyword">return</span> { + <span class="hljs-string">'request'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(config)</span> </span>{ + <span class="hljs-comment">// same as above</span> + }, + <span class="hljs-string">'response'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(response)</span> </span>{ + <span class="hljs-comment">// same as above</span> + } + }; +});</code></pre><h3 id="directives">Directives</h3> +<h4 id="composite">Composite</h4> +<blockquote> +<p>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/composite.svg" alt="Composite" title="Fig. 3"></p> +<p>According to the Gang of Four, MVC is nothing more than combination of:</p> +<ul class="list"> +<li>Strategy</li> +<li>Composite</li> +<li>Observer</li> +</ul> +<p>They state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.</p> +<p>Lets look at the following example:</p> +<pre class="hljs"><code><span class="hljs-doctype"><!doctype html></span> +<span class="hljs-tag"><<span class="hljs-title">html</span>></span> + <span class="hljs-tag"><<span class="hljs-title">head</span>></span> + <span class="hljs-tag"></<span class="hljs-title">head</span>></span> + <span class="hljs-tag"><<span class="hljs-title">body</span>></span> + <span class="hljs-tag"><<span class="hljs-title">zippy</span> <span class="hljs-attribute">title</span>=<span class="hljs-value">"Zippy"</span>></span> + Zippy! + <span class="hljs-tag"></<span class="hljs-title">zippy</span>></span> + <span class="hljs-tag"></<span class="hljs-title">body</span>></span> +<span class="hljs-tag"></<span class="hljs-title">html</span>></span></code></pre><pre class="hljs"><code>myModule.directive('zippy', function () { + <span class="hljs-keyword">return</span> { + restrict: 'E', + <span class="hljs-keyword">template</span>: '<<span class="hljs-keyword">div</span>><<span class="hljs-keyword">div</span> class=<span class="hljs-string">"header"</span>></<span class="hljs-keyword">div</span>><<span class="hljs-keyword">div</span> class=<span class="hljs-string">"content"</span> ng-transclude></<span class="hljs-keyword">div</span>></<span class="hljs-keyword">div</span>>', + link: function (scope, el) { + el.find('.header').click(function () { + el.find('.content').toggle(); + }); + } + } +});</code></pre><p>This example defines a simple directive, which is a UI component. The defined component (called "zippy") has header and content. Click on its header toggles the visibility of the content.</p> +<p>From the first example we can note that the whole DOM tree is a composition of elements. The root component is the <code>html</code> element, directly followed by the nested elements <code>head</code> and <code>body</code> and so on...</p> +<p>In the second, JavaScript, example we see that the <code>template</code> property of the directive, contains markup with <code>ng-transclude</code> directive inside it. So this means that inside the directive <code>zippy</code> we have another directive called <code>ng-transclude</code>, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.</p> +<h3 id="interpreter">Interpreter</h3> +<blockquote> +<p>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/interpreter.svg" alt="Interpreter" title="Fig. 6"></p> +<p>Behind its <code>$parse</code> service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. +The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:</p> +<ul class="list"> +<li>may contain filters with UNIX like pipe syntax</li> +<li>don't throw any errors</li> +<li>don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)</li> +<li>are evaluated in given context (the context of the current <code>$scope</code>)</li> +</ul> +<p>Inside the <code>$parse</code> service are defined two main components:</p> +<pre class="hljs"><code><span class="hljs-comment">//Responsible for converting given string into tokens</span> +<span class="hljs-keyword">var</span> Lexer; +<span class="hljs-comment">//Responsible for parsing the tokens and evaluating the expression</span> +<span class="hljs-keyword">var</span> Parser;</code></pre><p>Once given expression have been tokenized it is cached internally, because of performance concerns.</p> +<p>The terminal expressions in the AngularJS DSL are defined as follows:</p> +<pre class="hljs"><code><span class="hljs-keyword">var</span> OPERATORS = { + <span class="hljs-comment">/* jshint bitwise : false */</span> + <span class="hljs-string">'null'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;}, + <span class="hljs-string">'true'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;}, + <span class="hljs-string">'false'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;}, + undefined:noop, + <span class="hljs-string">'+'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{ + <span class="hljs-comment">//...</span> + }, + <span class="hljs-string">'*'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)*b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'/'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)/b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'%'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)%b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'^'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)^b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'='</span>:noop, + <span class="hljs-string">'==='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a, b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)===b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'!=='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a, b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)!==b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'=='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)==b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'!='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)!=b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'<'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)<b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'>'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)>b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'<='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)<=b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'>='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)>=b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'&&'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)&&b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'||'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)||b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'&'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)&b(<span class="hljs-keyword">self</span>, locals);}, + <span class="hljs-string">'|'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> b(<span class="hljs-keyword">self</span>, locals)(<span class="hljs-keyword">self</span>, locals, a(<span class="hljs-keyword">self</span>, locals));}, + <span class="hljs-string">'!'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a)</span></span>{<span class="hljs-keyword">return</span> !a(<span class="hljs-keyword">self</span>, locals);} +};</code></pre><p>We can think of the function associated with each terminal as implementation of the <code>AbstractExpression</code>'s interface.</p> +<p>Each <code>Client</code> interprets given AngularJS expression in a specific context - specific scope.</p> +<p>Few sample AngularJS expressions are:</p> +<pre class="hljs"><code>// toUpperCase filter <span class="hljs-keyword">is</span> applied to the <span class="hljs-literal">result</span> <span class="hljs-keyword">of</span> the expression +// (foo) ? bar : baz +(foo) ? bar : baz | toUpperCase</code></pre><h4 id="template-view">Template View</h4> +<blockquote> +<p>Renders information into HTML by embedding markers in an HTML page.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/template-view.svg" alt="Template View" title="Fig. 8"></p> +<p>The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.</p> +<p>Templates are very commonly used especially in the back-end. +For example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.</p> +<p>For JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as <code>script</code> embedded inside your view or even inlined into your JavaScript.</p> +<p>For example:</p> +<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"template/mustache"</span>></span><span class="javascript"> + <h2>Names<<span class="hljs-regexp">/h2> + </span></span></span><span class="hljs-expression">{{<span class="hljs-begin-block">#names</span>}}</span><span class="xml"><span class="javascript"> + <strong></span></span><span class="hljs-expression">{{<span class="hljs-variable">name</span>}}</span><span class="xml"><span class="javascript"><<span class="hljs-regexp">/strong> + </span></span></span><span class="hljs-expression">{{<span class="hljs-end-block">/names</span>}}</span><span class="xml"><span class="javascript"> +</span><span class="hljs-tag"></<span class="hljs-title">script</span>></span></span></code></pre><p>The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.</p> +<p>For example if we evaluate the template above in the context of the following object: <code>{ names: ['foo', 'bar', 'baz'] }</code>, so we will get:</p> +<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">h2</span>></span>Names<span class="hljs-tag"></<span class="hljs-title">h2</span>></span> + <span class="hljs-tag"><<span class="hljs-title">strong</span>></span>foo<span class="hljs-tag"></<span class="hljs-title">strong</span>></span> + <span class="hljs-tag"><<span class="hljs-title">strong</span>></span>bar<span class="hljs-tag"></<span class="hljs-title">strong</span>></span> + <span class="hljs-tag"><<span class="hljs-title">strong</span>></span>baz<span class="hljs-tag"></<span class="hljs-title">strong</span>></span></code></pre><p>AngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are. +What AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.</p> +<p>For example:</p> +<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">ul</span> <span class="hljs-attribute">ng-repeat</span>=<span class="hljs-value">"name in names"</span>></span> + <span class="hljs-tag"><<span class="hljs-title">li</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">name</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">li</span>></span> +<span class="hljs-tag"></<span class="hljs-title">ul</span>></span></span></code></pre><p>in the context of the scope:</p> +<pre class="hljs"><code><span class="hljs-variable">$scope</span>.names = [<span class="hljs-string">'foo'</span>, <span class="hljs-string">'bar'</span>, <span class="hljs-string">'baz'</span>];</code></pre><p>will produce the same result as the one above. The main difference here is that the template is not wrapped inside a <code>script</code> tag but is HTML instead.</p> +<h3 id="scope">Scope</h3> +<h4 id="observer">Observer</h4> +<blockquote> +<p>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg" alt="Observer" title="Fig. 7"></p> +<p>There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see <a href="#scope">Scope</a>). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.</p> +<p>Each AngularJS scope has public methods called <code>$on</code>, <code>$emit</code> and <code>$broadcast</code>. The method <code>$on</code> accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the <code>Observer</code> interface (in JavaScript the functions are first-class, so we can provide only implementation of the <code>notify</code> method):</p> +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExampleCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'event-name'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span><span class="hljs-params">()</span> </span>{ + <span class="hljs-comment">//body</span> + }); +}</code></pre><p>In this way the current scope "subscribes" to events of type <code>event-name</code>. When <code>event-name</code> is triggered in any parent or child scope of the given one, <code>handler</code> would be called.</p> +<p>The methods <code>$emit</code> and <code>$broadcast</code> are used for triggering events respectively upwards and downwards through the scope chain. +For example:</p> +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExampleCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$emit</span>(<span class="hljs-string">'event-name'</span>, { foo: <span class="hljs-string">'bar'</span> }); +}</code></pre><p>The scope in the example above, triggers the event <code>event-name</code> to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event <code>event-name</code>, would be notified and their handler callback will be invoked.</p> +<p>Analogical is the case when the method <code>$broadcast</code> is called. The only difference is that the event would be transmitted downwards - to all children scopes. +Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).</p> +<p>In the JavaScript community this pattern is better known as publish/subscribe.</p> +<h4 id="chain-of-responsibilities">Chain of Responsibilities</h4> +<blockquote> +<p>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/chain-of-responsibilities.svg" alt="Chain of Responsibilities" title="Fig. 5"></p> +<p>As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their <code>$parent</code> property.</p> +<p>When <code>$emit</code> or <code>$broadcast</code> are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:</p> +<ul class="list"> +<li>Handle the event and pass it to the next scope in the chain</li> +<li>Handle the event and stop its propagation</li> +<li>Pass the event to the next scope in the chain without handling it</li> +<li>Stop the event propagation without handling it</li> +</ul> +<p>In the example bellow you can see an example in which <code>ChildCtrl</code> triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in <code>ParentCtrl</code> and the one used in <code>MainCtrl</code>) are going to handle the event by logging into the console: <code>"foo received"</code>. If any of the scopes should be considered as final destination it can call the method <code>stopPropagation</code> of the event object, passed to the callback.</p> +<pre class="hljs"><code>myModule.controller(<span class="hljs-string">'MainCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + console.log(<span class="hljs-string">'foo received'</span>); + }); +}); + +myModule.controller(<span class="hljs-string">'ParentCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{ + console.log(<span class="hljs-string">'foo received'</span>); + }); +}); + +myModule.controller(<span class="hljs-string">'ChildCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$emit</span>(<span class="hljs-string">'foo'</span>); +});</code></pre><p>The different handlers from the UML diagram above are the different scopes, injected to the controllers.</p> +<h4 id="command">Command</h4> +<blockquote> +<p>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/command.svg" alt="Command" title="Fig. 11"></p> +<p>Before continuing with the application of the command pattern lets describe how AngularJS implements data binding.</p> +<p>When we want to bind our model to the view we use the directives <code>ng-bind</code> (for single-way data binding) and <code>ng-model</code> (for two-way data binding). For example, if we want each change in the model <code>foo</code> to reflect the view we can:</p> +<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">span</span> <span class="hljs-attribute">ng-bind</span>=<span class="hljs-value">"foo"</span>></span><span class="hljs-tag"></<span class="hljs-title">span</span>></span></code></pre><p>Now each time we change the value of <code>foo</code> the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:</p> +<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">span</span> <span class="hljs-attribute">ng-bind</span>=<span class="hljs-value">"foo + ' ' + bar | uppercase"</span>></span><span class="hljs-tag"></<span class="hljs-title">span</span>></span></code></pre><p>In the example above the value of the span will be the concatenated uppercased value of <code>foo</code> and <code>bar</code>. What happens behind the scene?</p> +<p>Each <code>$scope</code> has method called <code>$watch</code>. When the AngularJS compiler find the directive <code>ng-bind</code> it creates a new watcher of the expression <code>foo + ' ' + bar | uppercase</code>, i.e. <code>$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });</code>. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.</p> +<p>Here are the first a couple of lines of the implementation of <code>$watch</code>:</p> +<pre class="hljs"><code>$watch: <span class="hljs-keyword">function</span>(watchExp, listener, objectEquality) { + var scope = this, + get = compileToFn(watchExp, <span class="hljs-string">'watch'</span>), + array = scope.$$watchers, + watcher = { + fn: listener, + last: initWatchVal, + get: get, + exp: watchExp, + eq: !!objectEquality + }; +//<span class="hljs-keyword">...</span></code></pre><p>We can think of the <code>watcher</code> object as a command. The expression of the command is being evaluated on each <a href="https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest"><code>"$digest"</code></a> loop. Once AngularJS detects change in the expression, it invokes the <code>listener</code> function. The <code>watcher</code> command encapsulates the whole information required for watching given expression and delegates the execution of the command to the <code>listener</code> (the actual receiver). We can think of the <code>$scope</code> as the command's <code>Client</code> and the <code>$digest</code> loop as the command's <code>Invoker</code>.</p> +<h3 id="controllers">Controllers</h3> +<h4 id="page-controller">Page Controller</h4> +<blockquote> +<p>An object that handles a request for a specific page or action on a Web site. Martin Fowler</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/page-controller.svg" alt="Page Controller" title="Fig. 8"></p> +<p>According to <a href="#references">4</a> the page controller:</p> +<blockquote> +<p>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code</p> +</blockquote> +<p>Since there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the <code>$route</code> or <code>$state</code> services and the page rendering is responsibility of the directives <code>ng-view</code>/<code>ui-view</code>.</p> +<p>Similarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.</p> +<p>The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap. +Here is an example hierarchy between few controllers:</p> +<pre class="hljs"><code><span class="xml"><span class="hljs-doctype"><!doctype html></span> +<span class="hljs-tag"><<span class="hljs-title">html</span>></span> + <span class="hljs-tag"><<span class="hljs-title">head</span>></span> + <span class="hljs-tag"></<span class="hljs-title">head</span>></span> + <span class="hljs-tag"><<span class="hljs-title">body</span> <span class="hljs-attribute">ng-controller</span>=<span class="hljs-value">"MainCtrl"</span>></span> + <span class="hljs-tag"><<span class="hljs-title">div</span> <span class="hljs-attribute">ng-controller</span>=<span class="hljs-value">"ChildCtrl"</span>></span> + <span class="hljs-tag"><<span class="hljs-title">span</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">user.name</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">span</span>></span> + <span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">ng-click</span>=<span class="hljs-value">"click()"</span>></span>Click<span class="hljs-tag"></<span class="hljs-title">button</span>></span> + <span class="hljs-tag"></<span class="hljs-title">div</span>></span> + <span class="hljs-tag"></<span class="hljs-title">body</span>></span> +<span class="hljs-tag"></<span class="hljs-title">html</span>></span></span></code></pre><pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MainCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, <span class="hljs-variable">$location</span>, User)</span> </span>{ + <span class="hljs-keyword">if</span> (!User.isAuthenticated()) { + <span class="hljs-variable">$location</span>.path(<span class="hljs-string">'/unauthenticated'</span>); + } +} + +<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ChildCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, User)</span> </span>{ + <span class="hljs-variable">$scope</span>.click = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + alert(<span class="hljs-string">'You clicked me!'</span>); + }; + <span class="hljs-variable">$scope</span>.user = User.get(<span class="hljs-number">0</span>); +}</code></pre><p>This example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.</p> +<p>The <code>ChildCtrl</code> is responsible for handling actions such as clicking the button with label <code>"Click"</code> and exposing the model to the view, by attaching it to the scope.</p> +<h3 id="others">Others</h3> +<h4 id="module-pattern">Module Pattern</h4> +<p>This is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.</p> +<p>Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:</p> +<pre class="hljs"><code><span class="hljs-keyword">var</span> Page = (<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + + <span class="hljs-keyword">var</span> title; + + <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setTitle</span><span class="hljs-params">(t)</span> </span>{ + <span class="hljs-built_in">document</span>.title = t; + title = t; + } + + <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTitle</span><span class="hljs-params">()</span> </span>{ + <span class="hljs-keyword">return</span> title; + } + + <span class="hljs-keyword">return</span> { + setTitle: setTitle, + getTitle: getTitle + }; +}());</code></pre><p>In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (<code>setTitle</code> and <code>getTitle</code>). The returned object is being assigned to the <code>Page</code> variable.</p> +<p>In this case the user of the <code>Page</code> object doesn't has direct access to the <code>title</code> variable, which is defined inside the local scope of the IIFE.</p> +<p>The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:</p> +<pre class="hljs"><code>app.factory(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ + + <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">privateMember</span><span class="hljs-params">()</span> </span>{ + <span class="hljs-comment">//body...</span> + } + + <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">publicMember</span><span class="hljs-params">()</span> </span>{ + <span class="hljs-comment">//body...</span> + privateMember(); + <span class="hljs-comment">//body</span> + } + + <span class="hljs-keyword">return</span> { + publicMember: publicMember + }; +});</code></pre><p>Once we want to inject <code>foo</code> inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.</p> +<h3 id="data-mapper">Data Mapper</h3> +<blockquote> +<p>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.</p> +</blockquote> +<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/data-mapper.svg" alt="Data Mapper" title="Fig. 10"></p> +<p>As the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).</p> +<p>Usually, if we have RESTful API <code>$resource</code> will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.</p> +<p>For instance, lets assume we have application in which each user has:</p> +<ul class="list"> +<li>name</li> +<li>address</li> +<li>list of friends</li> +</ul> +<p>And our API has the methods:</p> +<ul class="list"> +<li><code>GET /user/:id</code> - returns the user's name and the address of given user</li> +<li><code>GET /friends/:id</code> - returns the list of friends of given user</li> +</ul> +<p>Possible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called <code>User</code>, which loads the user's friends when we request the user:</p> +<pre class="hljs"><code>app.factory(<span class="hljs-string">'User'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">($q)</span> </span>{ + + <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">User</span><span class="hljs-params">(name, address, friends)</span> </span>{ + <span class="hljs-keyword">this</span>.name = name; + <span class="hljs-keyword">this</span>.address = address; + <span class="hljs-keyword">this</span>.friends = friends; + } + + User.<span class="hljs-keyword">get</span> = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(params)</span> </span>{ + <span class="hljs-keyword">var</span> user = $http.<span class="hljs-keyword">get</span>(<span class="hljs-string">'/user/'</span> + params.id), + friends = $http.<span class="hljs-keyword">get</span>(<span class="hljs-string">'/friends/'</span> + params.id); + $q.all([user, friends]) + .then(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(user, friends)</span> </span>{ + <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> User(user.name, user.address, friends); + }); + }; + <span class="hljs-keyword">return</span> User; +});</code></pre><p>This way we create pseudo-data mapper, which adapts our API according to the SPA requirements.</p> +<p>We can use the <code>User</code> service by:</p> +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MainCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, User)</span> </span>{ + User.get({ id: <span class="hljs-number">1</span> }) + .then(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(data)</span> </span>{ + <span class="hljs-variable">$scope</span>.user = data; + }); +}</code></pre><p>And the following partial:</p> +<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span> + <span class="hljs-tag"><<span class="hljs-title">div</span>></span> + Name: </span><span class="hljs-expression">{{<span class="hljs-variable">user.name</span>}}</span><span class="xml"> + <span class="hljs-tag"></<span class="hljs-title">div</span>></span> + <span class="hljs-tag"><<span class="hljs-title">div</span>></span> + Address: </span><span class="hljs-expression">{{<span class="hljs-variable">user.address</span>}}</span><span class="xml"> + <span class="hljs-tag"></<span class="hljs-title">div</span>></span> + <span class="hljs-tag"><<span class="hljs-title">div</span>></span> + Friends with ids: + <span class="hljs-tag"><<span class="hljs-title">ul</span>></span> + <span class="hljs-tag"><<span class="hljs-title">li</span> <span class="hljs-attribute">ng-repeat</span>=<span class="hljs-value">"friend in user.friends"</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">friend</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">li</span>></span> + <span class="hljs-tag"></<span class="hljs-title">ul</span>></span> + <span class="hljs-tag"></<span class="hljs-title">div</span>></span> +<span class="hljs-tag"></<span class="hljs-title">div</span>></span></span></code></pre><h2 id="references">References</h2> +<ol class="list"> +<li><a href="https://en.wikipedia.org/wiki">Wikipedia</a>. The source of all brief descriptions of the design patterns is wikipedia.</li> +<li><a href="https://docs.angularjs.org">AngularJS' documentation</a></li> +<li><a href="https://github.com/angular/angular.js">AngularJS' git repository</a></li> +<li><a href="http://msdn.microsoft.com/en-us/library/ff649595.aspx">Page Controller</a></li> +<li><a href="http://martinfowler.com/books/eaa.html">Patterns of Enterprise Application Architecture (P of EAA)</a></li> +<li><a href="http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html">Using Dependancy Injection to Avoid Singletons</a></li> +<li><a href="https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery">Why would one use the Publish/Subscribe pattern (in JS/jQuery)?</a></li> +</ol> + + </div> + </div> + </div> + <div id="sidebar"><ul class="nav nav-list"> + <li><a href="#angularjs-in-patterns">AngularJS in Patterns</a></li> + <li><a href="#table-of-contents">Table of Contents</a></li> + <li><a href="#abstract">Abstract</a></li> + <li><a href="#introduction">Introduction</a></li> + <li><a href="#angularjs-overview">AngularJS overview</a></li> + <li><a href="#partials">Partials</a></li> + <li><a href="#controllers">Controllers</a></li> + <li><a href="#scope">Scope</a></li> + <li><a href="#directives">Directives</a></li> + <li><a href="#filters">Filters</a></li> + <li><a href="#services">Services</a></li> + <li><a href="#angularjs-patterns">AngularJS Patterns</a></li> + <li><a href="#services">Services</a></li> + <li><a href="#singleton">Singleton</a></li> + <li><a href="#factory-method">Factory Method</a></li> + <li><a href="#decorator">Decorator</a></li> + <li><a href="#facade">Facade</a></li> + <li><a href="#proxy">Proxy</a></li> + <li><a href="#active-record">Active Record</a></li> + <li><a href="#intercepting-filters">Intercepting Filters</a></li> + <li><a href="#directives">Directives</a></li> + <li><a href="#composite">Composite</a></li> + <li><a href="#interpreter">Interpreter</a></li> + <li><a href="#template-view">Template View</a></li> + <li><a href="#scope">Scope</a></li> + <li><a href="#observer">Observer</a></li> + <li><a href="#chain-of-responsibilities">Chain of Responsibilities</a></li> + <li><a href="#command">Command</a></li> + <li><a href="#controllers">Controllers</a></li> + <li><a href="#page-controller">Page Controller</a></li> + <li><a href="#others">Others</a></li> + <li><a href="#module-pattern">Module Pattern</a></li> + <li><a href="#data-mapper">Data Mapper</a></li> + <li><a href="#references">References</a></li> +</ul> + </div> + <div class="clear"> + </div> + + <div id="footer"> + <p>By <a href="http://blog.mgechev.com/">Minko Gechev</a>.</p> + </div> + </div> +</body> +</html> diff --git a/README.md b/README.md deleted file mode 100644 index 19b96f9..0000000 --- a/README.md +++ /dev/null @@ -1,1089 +0,0 @@ -# AngularJS in Patterns - -## Table of Contents - -* [Abstract](#abstract) -* [Introduction](#introduction) -* [AngularJS overview](#angularjs-overview) -* [Partials](#partials) -* [Controllers](#controllers) -* [Scope](#scope) -* [Directives](#directives) -* [Filters](#filters) -* [Services](#services) -* [AngularJS Patterns](#angularjs-patterns) -* [Services](#services-1) - * [Singleton](#singleton) - * [Factory Method](#factory-method) - * [Decorator](#decorator) - * [Facade](#facade) - * [Proxy](#proxy) - * [Active Record](#active-record) - * [Intercepting Filters](#intercepting-filters) -* [Directives](#directives-1) - * [Composite](#composite) - * [Interpreter](#interpreter) - * [Template View](#template-view) -* [Scope](#scope-1) - * [Observer](#observer) - * [Chain of Responsibilities](#chain-of-responsibilities) - * [Command](#command) -* [Controller](#controller-1) - * [Page Controller](#page-controller) -* [Others](#others) - * [Module Pattern](#module-pattern) - * [Data Mapper](#data-mapper) -* [References](#references) - -## Abstract - -One of the best ways to learn something new is to see how the things you already know are used in it. -This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. -The goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application. - -## Introduction - -The document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned. - -The last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS. - -## AngularJS overview - -AngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA). -SPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand. -Since most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are: - -- two-way data binding -- dependency injection -- separation of concerns -- testability -- abstraction - -The separation of concerns is achieved by dividing each AngularJS application into separate components, such as: - -- partials -- controllers -- directives -- services -- filters - -These components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic. - -### Partials - -The partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example). - -Initially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework. - -**Sample partial** - -```HTML -<html ng-app> - <!-- Body tag augmented with ngController directive --> - <body ng-controller="MyController"> - <input ng-model="foo" value="bar"> - <!-- Button tag with ng-click directive, and - string expression 'buttonText' - wrapped in "{{ }}" markup --> - <button ng-click="changeFoo()">{{buttonText}}</button> - <script src="angular.js"></script> - </body> -</html> -``` - -With AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked. - -### Controllers - -The AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*. - -```JavaScript -function MyController($scope) { - $scope.buttonText = 'Click me to change foo!'; - $scope.foo = 42; - - $scope.changeFoo = function () { - $scope.foo += 1; - alert('Foo changed'); - }; -} -``` - -For example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways. - -1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding. -2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`. - -All the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones. - -### Scope - -In AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial. - -Another important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype. - -Scope inheritance is illustrated in the following example: - -```HTML -<div ng-controller="BaseCtrl"> - <div id="child" ng-controller="ChildCtrl"> - <button id="parent-method" ng-click="foo()">Parent method</button> - <button ng-click="bar()">Child method</button> - </div> -</div> -``` - -```JavaScript -function BaseCtrl($scope) { - $scope.foo = function () { - alert('Base foo'); - }; -} - -function ChildCtrl($scope) { - $scope.bar = function () { - alert('Child bar'); - }; -} -``` - -With `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`. - -### Directives - -In AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new direcrive or consider refactoring of already existing one, which could handle the required DOM manipulations. -Each directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as: - -- template -- compile function -- link function -- etc... - -By citing the name of the directives they can be used inside the declarative partials. - -Example: - -```JavaScript -myModule.directive('alertButton', function () { - return { - template: '<button ng-transclude></button>', - scope: { - content: '@' - }, - replace: true, - restrict: 'E', - transclude: true, - link: function (scope, el) { - el.click(function () { - alert(scope.content); - }); - } - }; -}); -``` - -```HTML -<alert-button content="42">Click me</alert-button> -``` - -In the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted. - -Since the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here. - -### Filters - -The filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection. - -Here is a definition of a sample filter, which changes the given string to uppercase: - -```JavaScript -myModule.filter('uppercase', function () { - return function (str) { - return (str || '').toUpperCase(); - }; -}); -``` - -Inside a partial this filter could be used using the Unix's piping syntax: - -```HTML -<div>{{ name | uppercase }}</div> -``` - -Inside a controller the filter could be used as follows: - -```JavaScript -function MyCtrl(uppercaseFilter) { - $scope.name = uppercaseFilter('foo'); //FOO -} -``` - -### Services - -Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service. - -```JavaScript -myModule.service('Developer', function () { - this.name = 'Foo'; - this.motherLanguage = 'JavaScript'; - this.live = function () { - while (true) { - this.code(); - } - }; -}); -``` - -The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives). - -```JavaScript -function MyCtrl(developer) { - var developer = new Developer(); - developer.live(); -} -``` - -## AngularJS Patterns - -In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components. - -In the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS. - -### Services - -#### Singleton - ->The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. - -In the UML diagram bellow is illustrated the singleton design pattern. - - - -When given dependency is required by any component, AngularJS resolves it using the following algorithm: - -- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility). -- If the dependency exists AngularJS pass it as parameter to the component, which requires it. -- If the dependency does not exists: - - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency. - - AngularJS caches it inside the hash map mentioned above. - - AngularJS passes it as parameter to the component, which requires it. - -We can take better look at the AngularJS' source code, which implements the method `getService`: - -```JavaScript -function getService(serviceName) { - if (cache.hasOwnProperty(serviceName)) { - if (cache[serviceName] === INSTANTIATING) { - throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); - } - return cache[serviceName]; - } else { - try { - path.unshift(serviceName); - cache[serviceName] = INSTANTIATING; - return cache[serviceName] = factory(serviceName); - } catch (err) { - if (cache[serviceName] === INSTANTIATING) { - delete cache[serviceName]; - } - throw err; - } finally { - path.shift(); - } - } -} -``` - -We can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`). - -This way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation: - -- It improves the testability of your source code -- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy) - -For further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered. - -#### Factory Method - ->The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor. - - - -Lets consider the following snippet: - -```JavaScript -myModule.config(function ($provide) { - $provide.provider('foo', function () { - var baz = 42; - return { - //Factory method - $get: function (bar) { - var baz = bar.baz(); - return { - baz: baz - }; - } - }; - }); -}); - -``` - -In the code above we use the `config` callback in order to define new "provider". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way. - -Each service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance. - -We can dig a little bit deeper in AngularJS' implementation: - -```JavaScript -//... - -createInternalInjector(instanceCache, function(servicename) { - var provider = providerInjector.get(servicename + providerSuffix); - return instanceInjector.invoke(provider.$get, provider, undefined, servicename); -}, strictDi)); - -//... - -function invoke(fn, self, locals, serviceName){ - if (typeof locals === 'string') { - serviceName = locals; - locals = null; - } - - var args = [], - $inject = annotate(fn, strictDi, serviceName), - length, i, - key; - - for(i = 0, length = $inject.length; i < length; i++) { - key = $inject[i]; - if (typeof key !== 'string') { - throw $injectorMinErr('itkn', - 'Incorrect injection token! Expected service name as string, got {0}', key); - } - args.push( - locals && locals.hasOwnProperty(key) - ? locals[key] - : getService(key) - ); - } - if (!fn.$inject) { - // this means that we must be an array. - fn = fn[length]; - } - - return fn.apply(self, args); -} -``` - -From the example above we can notice how the `$get` method is actually used: - -```JavaScript -instanceInjector.invoke(provider.$get, provider, undefined, servicename) -``` - -The snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`. - -If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product". - -There are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like: - -- The most appropriate moment, when the component needs to be instantiated -- Resolving all the dependencies required by the component -- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers) - -#### Decorator - ->The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. - - - -AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create "wrapper" of any service you have previously defined or used by a third-party: - -```JavaScript -myModule.controller('MainCtrl', function (foo) { - foo.bar(); -}); - -myModule.factory('foo', function () { - return { - bar: function () { - console.log('I\'m bar'); - }, - baz: function () { - console.log('I\'m baz'); - } - }; -}); - -myModule.config(function ($provide) { - $provide.decorator('foo', function ($delegate) { - var barBackup = $delegate.bar; - $delegate.bar = function () { - console.log('Decorated'); - barBackup.apply($delegate, arguments); - }; - return $delegate; - }); -}); -``` -The example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `"foo"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function. -We decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context. - -Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop). - -#### Facade - ->A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can: - ->1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks; - ->2. make the library more readable, for the same reason; - ->3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system; - ->4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs). - - - -There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade. - -For example, lets take a look how we can create an `XMLHttpRequest` POST request: - -```JavaScript -var http = new XMLHttpRequest(), - url = '/example/new', - params = encodeURIComponent(data); -http.open("POST", url, true); - -http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); -http.setRequestHeader("Content-length", params.length); -http.setRequestHeader("Connection", "close"); - -http.onreadystatechange = function () { - if(http.readyState == 4 && http.status == 200) { - alert(http.responseText); - } -} -http.send(params); -``` -But if we want to post this data using the AngularJS' `$http` service we can: - -```JavaScript -$http({ - method: 'POST', - url: '/example/new', - data: data -}) -.then(function (response) { - alert(response); -}); -``` -or we can even: - -```JavaScript -$http.post('/someUrl', data) -.then(function (response) { - alert(response); -}); -``` -The second option provides pre-configured version, which creates a HTTP POST request to the given URL. - -Even higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections. - -#### Proxy - ->A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. - - - -We can distinguish three different types of proxy: - -- Virtual Proxy -- Remote Proxy -- Protection Proxy - -In this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy. - -In the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`: - -```JavaScript -var User = $resource('/users/:id'), - user = User.get({ id: 42 }); -console.log(user); //{} -``` - -`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server. - -How does this works with AngularJS? Well, lets consider the following snippet: - -```JavaScript -function MainCtrl($scope, $resource) { - var User = $resource('/users/:id'), - $scope.user = User.get({ id: 42 }); -} -``` - -```html -<span ng-bind="user.name"></span> -``` -Initially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view. - -#### Active Record - ->The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication. - - - -AngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core. - -According to the AngularJS' documentation `$resource` is: - ->A factory which creates a resource object that lets you interact with RESTful server-side data sources. ->The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service. - -Here is how `$resource` could be used: - -```JavaScript -var User = $resource('/users/:id'), - user = new User({ - name: 'foo', - age : 42 - }); - -user.$save(); -``` - -The call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations. - -This way we can use the constructor function and its static methods by: - -```JavaScript -User.get({ userid: userid }); -``` - -The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)). - -You can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource). - -Since Martin Fowler states that - -> responsibility of the Active Record object is to take care of the communication with the databse in order to create... - -`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as "Active Record like RESTful communication". - -#### Intercepting Filters - ->Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request. - - - -In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one. - -In AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`. - -`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error. - -Here is a basic example how you can add interceptors using object literal: - -```JavaScript -$httpProvider.interceptors.push(function($q, dependency1, dependency2) { - return { - 'request': function(config) { - // same as above - }, - 'response': function(response) { - // same as above - } - }; -}); -``` - -### Directives - -#### Composite - ->The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. - - - -According to the Gang of Four, MVC is nothing more than combination of: - -- Strategy -- Composite -- Observer - -They state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied. - -Lets look at the following example: - -```HTML -<!doctype html> -<html> - <head> - </head> - <body> - <zippy title="Zippy"> - Zippy! - </zippy> - </body> -</html> -``` - -```JavaScript -myModule.directive('zippy', function () { - return { - restrict: 'E', - template: '<div><div class="header"></div><div class="content" ng-transclude></div></div>', - link: function (scope, el) { - el.find('.header').click(function () { - el.find('.content').toggle(); - }); - } - } -}); -``` - -This example defines a simple directive, which is a UI component. The defined component (called "zippy") has header and content. Click on its header toggles the visibility of the content. - -From the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on... - -In the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node. - -### Interpreter - ->In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence. - - - -Behind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. -The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions: - -- may contain filters with UNIX like pipe syntax -- don't throw any errors -- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator) -- are evaluated in given context (the context of the current `$scope`) - -Inside the `$parse` service are defined two main components: - -```JavaScript -//Responsible for converting given string into tokens -var Lexer; -//Responsible for parsing the tokens and evaluating the expression -var Parser; -``` - -Once given expression have been tokenized it is cached internally, because of performance concerns. - -The terminal expressions in the AngularJS DSL are defined as follows: - -```JavaScript -var OPERATORS = { - /* jshint bitwise : false */ - 'null':function(){return null;}, - 'true':function(){return true;}, - 'false':function(){return false;}, - undefined:noop, - '+':function(self, locals, a,b){ - //... - }, - '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);}, - '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);}, - '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);}, - '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);}, - '=':noop, - '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);}, - '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);}, - '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);}, - '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);}, - '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);}, - '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);}, - '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);}, - '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);}, - '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);}, - '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);}, - '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);}, - '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));}, - '!':function(self, locals, a){return !a(self, locals);} -}; -``` - -We can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface. - -Each `Client` interprets given AngularJS expression in a specific context - specific scope. - -Few sample AngularJS expressions are: - -```JavaScript -// toUpperCase filter is applied to the result of the expression -// (foo) ? bar : baz -(foo) ? bar : baz | toUpperCase -``` - -#### Template View - -> Renders information into HTML by embedding markers in an HTML page. - - - -The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format. - -Templates are very commonly used especially in the back-end. -For example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages. - -For JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript. - -For example: - -```html -<script type="template/mustache"> - <h2>Names</h2> - {{#names}} - <strong>{{name}}</strong> - {{/names}} -</script> -``` - -The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value. - -For example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get: - -```html -<h2>Names</h2> - <strong>foo</strong> - <strong>bar</strong> - <strong>baz</strong> -``` - -AngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are. -What AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope. - -For example: - -```html -<ul ng-repeat="name in names"> - <li>{{name}}</li> -</ul> -``` - -in the context of the scope: - -```javascript -$scope.names = ['foo', 'bar', 'baz']; -``` - -will produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead. - - -### Scope - -#### Observer - ->The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. - - - -There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes. - -Each AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method): - -```JavaScript -function ExampleCtrl($scope) { - $scope.$on('event-name', function handler() { - //body - }); -} -``` - -In this way the current scope "subscribes" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called. - -The methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain. -For example: - -```JavaScript -function ExampleCtrl($scope) { - $scope.$emit('event-name', { foo: 'bar' }); -} -``` - -The scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked. - -Analogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes. -Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event). - -In the JavaScript community this pattern is better known as publish/subscribe. - -#### Chain of Responsibilities - ->The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain. - - - -As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property. - -When `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may: - -- Handle the event and pass it to the next scope in the chain -- Handle the event and stop its propagation -- Pass the event to the next scope in the chain without handling it -- Stop the event propagation without handling it - -In the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `"foo received"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback. - -```JavaScript -myModule.controller('MainCtrl', function ($scope) { - $scope.$on('foo', function () { - console.log('foo received'); - }); -}); - -myModule.controller('ParentCtrl', function ($scope) { - $scope.$on('foo', function (e) { - console.log('foo received'); - }); -}); - -myModule.controller('ChildCtrl', function ($scope) { - $scope.$emit('foo'); -}); -``` - -The different handlers from the UML diagram above are the different scopes, injected to the controllers. - -#### Command - ->In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters. - - - -Before continuing with the application of the command pattern lets describe how AngularJS implements data binding. - -When we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can: - -```html -<span ng-bind="foo"></span> -``` - -Now each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like: - -```html -<span ng-bind="foo + ' ' + bar | uppercase"></span> -``` - -In the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene? - -Each `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span. - -Here are the first a couple of lines of the implementation of `$watch`: - -```javascript -$watch: function(watchExp, listener, objectEquality) { - var scope = this, - get = compileToFn(watchExp, 'watch'), - array = scope.$$watchers, - watcher = { - fn: listener, - last: initWatchVal, - get: get, - exp: watchExp, - eq: !!objectEquality - }; -//... -``` - -We can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`"$digest"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`. - -### Controllers - -#### Page Controller - ->An object that handles a request for a specific page or action on a Web site. Martin Fowler - - - -According to [4](#references) the page controller: - ->Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code - -Since there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`. - -Similarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers. - -The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap. -Here is an example hierarchy between few controllers: - -```HTML -<!doctype html> -<html> - <head> - </head> - <body ng-controller="MainCtrl"> - <div ng-controller="ChildCtrl"> - <span>{{user.name}}</span> - <button ng-click="click()">Click</button> - </div> - </body> -</html> -``` - -```JavaScript -function MainCtrl($scope, $location, User) { - if (!User.isAuthenticated()) { - $location.path('/unauthenticated'); - } -} - -function ChildCtrl($scope, User) { - $scope.click = function () { - alert('You clicked me!'); - }; - $scope.user = User.get(0); -} -``` - -This example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction. - -The `ChildCtrl` is responsible for handling actions such as clicking the button with label `"Click"` and exposing the model to the view, by attaching it to the scope. - -### Others - -#### Module Pattern - -This is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy. - -Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module: - -```javascript -var Page = (function () { - - var title; - - function setTitle(t) { - document.title = t; - title = t; - } - - function getTitle() { - return title; - } - - return { - setTitle: setTitle, - getTitle: getTitle - }; -}()); -``` - -In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable. - -In this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE. - -The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy: - -```javascript -app.factory('foo', function () { - - function privateMember() { - //body... - } - - function publicMember() { - //body... - privateMember(); - //body - } - - return { - publicMember: publicMember - }; -}); -``` - -Once we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library. - -### Data Mapper - ->A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself. - - - -As the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.). - -Usually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end. - -For instance, lets assume we have application in which each user has: - -- name -- address -- list of friends - -And our API has the methods: - -- `GET /user/:id` - returns the user's name and the address of given user -- `GET /friends/:id` - returns the list of friends of given user - -Possible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user: - -```javascript -app.factory('User', function ($q) { - - function User(name, address, friends) { - this.name = name; - this.address = address; - this.friends = friends; - } - - User.get = function (params) { - var user = $http.get('/user/' + params.id), - friends = $http.get('/friends/' + params.id); - $q.all([user, friends]) - .then(function (user, friends) { - return new User(user.name, user.address, friends); - }); - }; - return User; -}); -``` - -This way we create pseudo-data mapper, which adapts our API according to the SPA requirements. - -We can use the `User` service by: - -```javascript -function MainCtrl($scope, User) { - User.get({ id: 1 }) - .then(function (data) { - $scope.user = data; - }); -} -``` - -And the following partial: - -```html -<div> - <div> - Name: {{user.name}} - </div> - <div> - Address: {{user.address}} - </div> - <div> - Friends with ids: - <ul> - <li ng-repeat="friend in user.friends">{{friend}}</li> - </ul> - </div> -</div> -``` - -## References - -1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia. -2. [AngularJS' documentation](https://docs.angularjs.org) -3. [AngularJS' git repository](https://github.com/angular/angular.js) -4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx) -5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html) -6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) -7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery) diff --git a/images/active-record.svg b/active-record.svg similarity index 100% rename from images/active-record.svg rename to active-record.svg diff --git a/assets/DroidSans.woff b/assets/DroidSans.woff new file mode 100644 index 0000000000000000000000000000000000000000..891ce425fcd0d7d0eac4a43af94d3c5a802ded32 GIT binary patch literal 26348 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 BsJ#FH literal 0 HcmV?d00001 diff --git a/assets/assert.css b/assets/assert.css new file mode 100644 index 0000000..60b6765 --- /dev/null +++ b/assets/assert.css @@ -0,0 +1,10 @@ +.FAIL b, .ERROR b { color: red; /* #990066 */ } +.PASS b { color: #73C836; } +input.runner { + margin-top: 0.1em; + margin-bottom: 1em; + font-size: large; + padding: 0.3em; +} +ol.runner { margin-bottom: 0.2em; } +pre.run { margin-bottom: 0.2em;} diff --git a/assets/hljs-github.min.css b/assets/hljs-github.min.css new file mode 100644 index 0000000..9b4f3aa --- /dev/null +++ b/assets/hljs-github.min.css @@ -0,0 +1,124 @@ +/* + +github.com style (c) Vasily Polovnyov <vast@whiteants.net> + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; + -webkit-text-size-adjust: none; +} + +.hljs-comment, +.diff .hljs-header, +.hljs-javadoc { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.css .rule .hljs-keyword, +.hljs-winutils, +.nginx .hljs-title, +.hljs-subst, +.hljs-request, +.hljs-status { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-hexcolor, +.ruby .hljs-constant { + color: #008080; +} + +.hljs-string, +.hljs-tag .hljs-value, +.hljs-phpdoc, +.hljs-dartdoc, +.tex .hljs-formula { + color: #d14; +} + +.hljs-title, +.hljs-id, +.scss .hljs-preprocessor { + color: #900; + font-weight: bold; +} + +.hljs-list .hljs-keyword, +.hljs-subst { + font-weight: normal; +} + +.hljs-class .hljs-title, +.hljs-type, +.vhdl .hljs-literal, +.tex .hljs-command { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-tag .hljs-title, +.hljs-rules .hljs-property, +.django .hljs-tag .hljs-keyword { + color: #000080; + font-weight: normal; +} + +.hljs-attribute, +.hljs-variable, +.lisp .hljs-body { + color: #008080; +} + +.hljs-regexp { + color: #009926; +} + +.hljs-symbol, +.ruby .hljs-symbol .hljs-string, +.lisp .hljs-keyword, +.clojure .hljs-keyword, +.scheme .hljs-keyword, +.tex .hljs-special, +.hljs-prompt { + color: #990073; +} + +.hljs-built_in { + color: #0086b3; +} + +.hljs-preprocessor, +.hljs-pragma, +.hljs-pi, +.hljs-doctype, +.hljs-shebang, +.hljs-cdata { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.diff .hljs-change { + background: #0086b3; +} + +.hljs-chunk { + color: #aaa; +} diff --git a/assets/jquery-1.6.1.min.js b/assets/jquery-1.6.1.min.js new file mode 100644 index 0000000..b2ac174 --- /dev/null +++ b/assets/jquery-1.6.1.min.js @@ -0,0 +1,18 @@ +/*! + * jQuery JavaScript Library v1.6.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Thu May 12 15:04:36 2011 -0400 + */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!cj[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),c.body.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write("<!doctype><html><body></body></html>");b=cl.createElement(a),cl.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ck)}cj[a]=d}return cj[a]}function cu(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function ct(){cq=b}function cs(){setTimeout(ct,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bF.test(a)?d(a,e):b_(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bU,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bQ),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bD(a,b,c){var d=b==="width"?bx:by,e=b==="width"?a.offsetWidth:a.offsetHeight;if(c==="border")return e;f.each(d,function(){c||(e-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?e+=parseFloat(f.css(a,"margin"+this))||0:e-=parseFloat(f.css(a,"border"+this+"Width"))||0});return e}function bn(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bm(a){f.nodeName(a,"input")?bl(a):a.getElementsByTagName&&f.grep(a.getElementsByTagName("input"),bl)}function bl(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bk(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bj(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bi(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bh(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function X(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(S.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function W(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function O(a,b){return(a&&a!=="*"?a+".":"")+b.replace(A,"`").replace(B,"&")}function N(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(y,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function L(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function F(){return!0}function E(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.1",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:E?function(a){return a==null?"":E.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?C.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(F)return F.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=D.call(arguments,2),g=function(){return a.apply(c,f.concat(D.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){G["[object "+b+"]"]=b.toLowerCase()}),x=e.uaMatch(w),x.browser&&(e.browser[x.browser]=!0,e.browser.version=x.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?z=function(){c.removeEventListener("DOMContentLoaded",z,!1),e.ready()}:c.attachEvent&&(z=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",z),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g](h)}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};f=c.createElement("select"),g=f.appendChild(c.createElement("option")),h=a.getElementsByTagName("input")[0],j={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},h.checked=!0,j.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,j.optDisabled=!g.disabled;try{delete a.test}catch(s){j.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function b(){j.noCloneEvent=!1,a.detachEvent("onclick",b)}),a.cloneNode(!0).fireEvent("onclick")),h=c.createElement("input"),h.value="t",h.setAttribute("type","radio"),j.radioValue=h.value==="t",h.setAttribute("checked","checked"),a.appendChild(h),k=c.createDocumentFragment(),k.appendChild(a.firstChild),j.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",l=c.createElement("body"),m={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(q in m)l.style[q]=m[q];l.appendChild(a),b.insertBefore(l,b.firstChild),j.appendChecked=h.checked,j.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,j.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",j.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",n=a.getElementsByTagName("td"),r=n[0].offsetHeight===0,n[0].style.display="",n[1].style.display="none",j.reliableHiddenOffsets=r&&n[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(i=c.createElement("div"),i.style.width="0",i.style.marginRight="0",a.appendChild(i),j.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(i,null)||{marginRight:0}).marginRight,10)||0)===0),l.innerHTML="",b.removeChild(l);if(a.attachEvent)for(q in{submit:1,change:1,focusin:1})p="on"+q,r=p in a,r||(a.setAttribute(p,"return;"),r=typeof a[p]=="function"),j[q+"Bubbles"]=r;return j}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u=/\:/,v,w;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.addClass(a.call(this,b,c.attr("class")||""))});if(a&&typeof a=="string"){var b=(a||"").split(o);for(var c=0,d=this.length;c<d;c++){var e=this[c];if(e.nodeType===1)if(!e.className)e.className=a;else{var g=" "+e.className+" ",h=e.className;for(var i=0,j=b.length;i<j;i++)g.indexOf(" "+b[i]+" ")<0&&(h+=" "+b[i]);e.className=f.trim(h)}}}return this},removeClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.removeClass(a.call(this,b,c.attr("class")))});if(a&&typeof a=="string"||a===b){var c=(a||"").split(o);for(var d=0,e=this.length;d<e;d++){var g=this[d];if(g.nodeType===1&&g.className)if(a){var h=(" "+g.className+" ").replace(n," ");for(var i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){var d=f(this);d.toggleClass(a.call(this,c,d.attr("class"),b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;return(e.value||"").replace(p,"")}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);c=j&&f.attrFix[c]||c,i=f.attrHooks[c],i||(!t.test(c)||typeof d!="boolean"&&d!==b&&d.toLowerCase()!==c.toLowerCase()?v&&(f.nodeName(a,"form")||u.test(c))&&(i=v):i=w);if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j)return i.get(a,c);h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);c=i&&f.propFix[c]||c,h=f.propHooks[c];return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return a[f.propFix[c]||c]?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=b),a.setAttribute(c,c.toLowerCase()));return c}},f.attrHooks.value={get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return a.value},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=Object.prototype.hasOwnProperty,y=/\.(.*)$/,z=/^(?:textarea|input|select)$/i,A=/\./g,B=/ /g,C=/[^\w\s.|`]/g,D=function(a){return a.replace(C,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=E;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=E);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),D).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem +)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,O(a.origType,a.selector),f.extend({},a,{handler:N,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,O(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?F:E):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=F;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=F;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=F,this.stopPropagation()},isDefaultPrevented:E,isPropagationStopped:E,isImmediatePropagationStopped:E};var G=function(a){var b=a.relatedTarget;a.type=a.data;try{if(b&&b!==c&&!b.parentNode)return;while(b&&b!==this)b=b.parentNode;b!==this&&f.event.handle.apply(this,arguments)}catch(d){}},H=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?H:G,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?H:G)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&f(b).closest("form").length&&L("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&L("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var I,J=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},K=function(c){var d=c.target,e,g;if(!!z.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=J(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:K,beforedeactivate:K,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&K.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&K.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",J(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in I)f.event.add(this,c+".specialChange",I[c]);return z.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return z.test(this.nodeName)}},I=f.event.special.change.filters,I.focus=I.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var M={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||E,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=y.exec(h),k="",j&&(k=j[0],h=h.replace(y,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,M[h]?(a.push(M[h]+k),h=h+k):h=(M[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+O(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+O(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var P=/Until$/,Q=/^(?:parents|prevUntil|prevAll)/,R=/,/,S=/^.[^:#\[\.,]*$/,T=Array.prototype.slice,U=f.expr.match.POS,V={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(X(this,a,!1),"not",a)},filter:function(a){return this.pushStack(X(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=U.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=U.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(W(c[0])||W(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=T.call(arguments);P.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!V[a]?f.unique(e):e,(this.length>1||R.test(d))&&Q.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y=/ jQuery\d+="(?:\d+|null)"/g,Z=/^\s+/,$=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,_=/<([\w:]+)/,ba=/<tbody/i,bb=/<|&#?\w+;/,bc=/<(?:script|object|embed|option|style)/i,bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Y,""):null;if(typeof a=="string"&&!bc.test(a)&&(f.support.leadingWhitespace||!Z.test(a))&&!bg[(_.exec(a)||["",""])[1].toLowerCase()]){a=a.replace($,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bh(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bn)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i=b&&b[0]?b[0].ownerDocument||b[0]:c;a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!bc.test(a[0])&&(f.support.checkClone||!bd.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bj(a,d),e=bk(a),g=bk(d);for(h=0;e[h];++h)bj(e[h],g[h])}if(b){bi(a,d);if(c){e=bk(a),g=bk(d);for(h=0;e[h];++h)bi(e[h],g[h])}}return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument|| +b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bb.test(k))k=b.createTextNode(k);else{k=k.replace($,"<$1></$2>");var l=(_.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=ba.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Z.test(k)&&o.insertBefore(b.createTextNode(Z.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bm(k[i]);else bm(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bo=/alpha\([^)]*\)/i,bp=/opacity=([^)]*)/,bq=/-([a-z])/ig,br=/([A-Z]|^ms)/g,bs=/^-?\d+(?:px)?$/i,bt=/^-?\d/,bu=/^[+\-]=/,bv=/[^+\-\.\de]+/g,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB,bC=function(a,b){return b.toUpperCase()};f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0,widows:!0,orphans:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d;if(h==="number"&&isNaN(d)||d==null)return;h==="string"&&bu.test(d)&&(d=+d.replace(bv,"")+parseFloat(f.css(a,c))),h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bq,bC)}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){a.offsetWidth!==0?e=bD(a,b,d):f.swap(a,bw,function(){e=bD(a,b,d)});if(e<=0){e=bz(a,b,b),e==="0px"&&bB&&(e=bB(a,b,b));if(e!=null)return e===""||e==="auto"?"0px":e}if(e<0||e==null){e=a.style[b];return e===""||e==="auto"?"0px":e}return typeof e=="string"?e:e+"px"}},set:function(a,b){if(!bs.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bp.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bo.test(g)?g.replace(bo,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,c){var d,e,g;c=c.replace(br,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bs.test(d)&&bt.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bE=/%20/g,bF=/\[\]$/,bG=/\r?\n/g,bH=/#.*$/,bI=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bJ=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bK=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bL=/^(?:GET|HEAD)$/,bM=/^\/\//,bN=/\?/,bO=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bP=/^(?:select|textarea)/i,bQ=/\s+/,bR=/([?&])_=[^&]*/,bS=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bT=f.fn.load,bU={},bV={},bW,bX;try{bW=e.href}catch(bY){bW=c.createElement("a"),bW.href="",bW=bW.href}bX=bS.exec(bW.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bT)return bT.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bO,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bP.test(this.nodeName)||bJ.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bG,"\r\n")}}):{name:b.name,value:c.replace(bG,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bW,isLocal:bK.test(bX[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bZ(bU),ajaxTransport:bZ(bV),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?ca(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=cb(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bI.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bH,"").replace(bM,bX[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bQ),d.crossDomain==null&&(r=bS.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bX[1]&&r[2]==bX[2]&&(r[3]||(r[1]==="http:"?80:443))==(bX[3]||(bX[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bU,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bL.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bN.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bR,"$1_="+x);d.url=y+(y===d.url?(bN.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bV,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bE,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq,cr=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cv(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cm.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=cn.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this),f.isFunction(d.old)&&d.old.call(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function h(a){return d.step(a)}var d=this,e=f.fx,g;this.startTime=cq||cs(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,h.elem=this.elem,h()&&f.timers.push(h)&&!co&&(cr?(co=1,g=function(){co&&(cr(g),e.tick())},cr(g)):co=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cq||cs(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){return this[0]?parseFloat(f.css(this[0],d,"padding")):null},f.fn["outer"+c]=function(a){return this[0]?parseFloat(f.css(this[0],d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/assets/prettify.css b/assets/prettify.css new file mode 100644 index 0000000..52748db --- /dev/null +++ b/assets/prettify.css @@ -0,0 +1,52 @@ +/* Pretty printing styles. Used with prettify.js. */ + +/* SPAN elements with the classes below are added by prettyprint. */ +.pln { color: #000 } /* plain text */ + +@media screen { + .str { color: #080 } /* string content */ + .kwd { color: #008 } /* a keyword */ + .com { color: #800 } /* a comment */ + .typ { color: #606 } /* a type name */ + .lit { color: #066 } /* a literal value */ + /* punctuation, lisp open bracket, lisp close bracket */ + .pun, .opn, .clo { color: #660 } + .tag { color: #008 } /* a markup tag name */ + .atn { color: #606 } /* a markup attribute name */ + .atv { color: #080 } /* a markup attribute value */ + .dec, .var { color: #606 } /* a declaration; a variable name */ + .fun { color: red } /* a function name */ +} + +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { color: #060 } + .kwd { color: #006; font-weight: bold } + .com { color: #600; font-style: italic } + .typ { color: #404; font-weight: bold } + .lit { color: #044 } + .pun, .opn, .clo { color: #440 } + .tag { color: #006; font-weight: bold } + .atn { color: #404 } + .atv { color: #060 } +} + +/* Put a border around prettyprinted code snippets. */ +pre.prettyprint { background: none; font-size: 14px;} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L5, +li.L6, +li.L7, +li.L8 { list-style-type: none } +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { background: #eee } diff --git a/assets/prettify.js b/assets/prettify.js new file mode 100644 index 0000000..eef5ad7 --- /dev/null +++ b/assets/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c< +f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&& +(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r= +{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length, +t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b=== +"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value", +m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m= +a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue= +j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m, +250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit", +PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})(); diff --git a/assets/runner.js b/assets/runner.js new file mode 100644 index 0000000..fe7deda --- /dev/null +++ b/assets/runner.js @@ -0,0 +1,35 @@ +var dummy = { + console: function(elementId) { + return { + log: function() { + var msg = ""; + for ( var i = 0; i < arguments.length; i++ ) { + msg += " " + JSON.stringify(arguments[i]); + } + jQuery("#results_"+elementId).append("<li class='LOG'><b>LOG</b> " + msg + "</li>"); + }, + error: function(msg){ + jQuery("#results_"+elementId).append("<li class='ERROR'><b>ERROR</b> " + msg + "</li>"); + } + } + } +}; + +function run(id) { + try { + var str = 'var console = dummy.console("'+id+'"); ' + jQuery('#block_'+id).text(); + (new Function('dummy', str ))(dummy); + } catch(e){ + var d = dummy.console(id); + d.error(e.message); + } +} + +$(document).ready(function() { + var i = 1; + jQuery(".run").each(function(idx, elem) { + jQuery(elem).attr('id','block_'+i).after('<ol id="results_'+i+'" class="runner"></ol><input type="button" value="Run" class="runner" onclick="run('+i+');">'); + i++; + }); + prettyPrint(); +}); diff --git a/assets/style.css b/assets/style.css new file mode 100644 index 0000000..b597dc6 --- /dev/null +++ b/assets/style.css @@ -0,0 +1,273 @@ +/* Minimal font */ +body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, +form, fieldset, input, p, blockquote, table, th, td, embed, object, hr { + padding: 0; + margin: 0; + } +table { + border-collapse: collapse; + border-spacing: 0; + } +fieldset, img, abbr { + border: 0; + } +address, caption, cite, code, dfn, em, +h1, h2, h3, h4, h5, h6, th, var { + font-weight: normal; + font-style: normal; + } +ul { + list-style: none; + } +caption, th { + text-align: left; + } +h1, h2, h3, h4, h5, h6 { + font-size: 1.0em; + } +q:before, q:after { + content: ''; + } +a, ins { + text-decoration: none; + } + +/* I was originally using Cantarell for the body text, but it just isn't as readable the usual suspects. */ + +body { + font-family: Helvetica, Arial, 'Liberation Sans', FreeSans, sans-serif; +} + +a { + color: #c00; +} + +hr { + color: #ededed; + background-color: #ededed; + height: 1px; + border: none; +} + +/* Header */ +#header { + margin-top: 2.029em; + margin-left: auto; + margin-right: auto; + width: 940px; + + position: relative; + height: 0em; +} + +#header h1 { + font-family: 'Andika', sans-serif; + font-size: 37px; + font-weight: normal; + line-height: 48px; +} +#header span { + font-size: 14px; +} + +#brand { + position: absolute; bottom: 0; left: 0; +} + +#navi { + position: absolute; + right:0; + bottom:0; +} + +#navi li { + display: inline; + list-style-type: none; + padding-right: 20px; +} + +div.clear { + clear: both; +} + +div.clear hr { + margin: 18px 0px; +} + +#wrapper { + margin-left: auto; + margin-right: auto; + width: 960px; +} + +#container { + width: 72%; + display: inline; + float: right; + margin-right: 5px; + margin-left: 15px; + overflow: visible; +} + +/* Content */ +#content { + font-size: 16px; + line-height: 26px; + /* max-width: 540px; Optimal formula = 30 * font size in px. */ + + /* text-align: justify; */ + margin-bottom: 0; + padding-bottom: 20px; + float: right; + + overflow: visible; + width: 100%; +} + +#sidebar { + width: 24%; + float: left; + position: fixed; +} + +/* Date widget */ +#content small{ + font-size: 10px; + color: #CCC; + padding: 10px 20px 5px 0px; + float: left; + text-transform: uppercase; +} +#content span.date { + font-size: 32px; + line-height: 0.8; + color: #C00; +} + +/* Post titles */ + +.post h1 { + font-size: 36px; + line-height: 1; + margin-bottom: 0.5em; +} + +.post h2 { + font-size: 24px; + text-align: left; + color: black; + line-height: 32px; + margin-bottom: 15px; +} + +.post p { + margin: 0 0 1.5em; + max-width: 580px; +} + +.post ul { +list-style-type: disc; +} + +.post ul, .post ol { + margin: 0 1.5em 1.5em 0; + padding-left: 3.333em; +} + +.post pre ul, .post pre ol { + margin: 0; + padding: 0; +} + +.post pre { + font-size: 14px; + + padding: 2em 1.6em 2em 1.2em; + vertical-align: top; + background: #F8F8F8; + border: 1px solid #E8E8E8; + border-width: 1px 1px 1px 6px; + margin: -0.5em 0 1.1em; +} + +.post pre, .post table { + margin: -1em 0 1em 0; + padding: .5em 1em; + background: #F6F6F6 repeat 0 0; +} + +.post pre, .post code, .post tt { + font-family: 'droid sans mono', 'lucida console', monospace; + line-height: 1.5; +} + +.post h3 { + font-size: 1.5em; + line-height: 1; + margin-bottom: .5em; + padding-bottom: .5em; +} + +.post h4 { + font-size: 1.2em; + line-height: 1.25; + margin-bottom: 1.25em; +} + +.post p tt, .post p code { + background: ghostWhite; + border: 1px solid #DEDEDE; + padding: 0 0.2em; +} + + + +#sidebar h2 { + font-size: 18px; + padding: 5px 0 10px 0; +} + +#sidebar h3 { + font-size: 1.5em; + line-height: 1; + border-bottom: 1px solid #CCC; + margin-bottom: .5em; + padding-bottom: .5em; +} + + +table { width: 100%; border-collapse: collapse; border-spacing: 0; } +table caption { text-align: center; } +table th { font-weight: bold; } +table th, table td { padding: 0.3em; vertical-align: top; border: solid 0.1em; } + +div.summary { + border-top: 3px solid #EEE; + border-bottom: 3px solid #EEE; + width: 580px; + color: #666; + margin-top: 2em; + margin-bottom: 1em; + padding-top: 1em; +} + +div.summary ul { + margin: 0 1.5em 1em 0; +} + +span.ref { + font-size: small; + color: #888; +} + +span.ref a { + color: #666; +} +div.notice { + border: 1px solid #E8E8E8; background-color: #FBFBDD; padding: .5em 1em; +} + +#bottom_navi { + font-size: larger; + margin: 8px; +} diff --git a/assets/sunburst.css b/assets/sunburst.css new file mode 100644 index 0000000..e441989 --- /dev/null +++ b/assets/sunburst.css @@ -0,0 +1,53 @@ +/* Pretty printing styles. Used with prettify.js. */ +/* Vim sunburst theme by David Leibovic */ + +pre .str, code .str { color: #65B042; } /* string - green */ +pre .kwd, code .kwd { color: #E28964; } /* keyword - dark pink */ +pre .com, code .com { color: #AEAEAE; font-style: italic; } /* comment - gray */ +pre .typ, code .typ { color: #89bdff; } /* type - light blue */ +pre .lit, code .lit { color: #3387CC; } /* literal - blue */ +pre .pun, code .pun { color: #fff; } /* punctuation - white */ +pre .pln, code .pln { color: #fff; } /* plaintext - white */ +pre .tag, code .tag { color: #89bdff; } /* html/xml tag - light blue */ +pre .atn, code .atn { color: #bdb76b; } /* html/xml attribute name - khaki */ +pre .atv, code .atv { color: #65B042; } /* html/xml attribute value - green */ +pre .dec, code .dec { color: #3387CC; } /* decimal - blue */ + +pre.prettyprint, code.prettyprint { + background-color: #000; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + -o-border-radius: 8px; + -ms-border-radius: 8px; + -khtml-border-radius: 8px; + border-radius: 8px; +} + +pre.prettyprint { + width: 95%; + margin: 1em auto; + padding: 1em; + white-space: pre-wrap; + + font-size: 14px; +} + + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE; } /* IE indents via margin-left */ +li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none } +/* Alternate shading for lines */ +li.L1,li.L3,li.L5,li.L7,li.L9 { } + +@media print { + pre .str, code .str { color: #060; } + pre .kwd, code .kwd { color: #006; font-weight: bold; } + pre .com, code .com { color: #600; font-style: italic; } + pre .typ, code .typ { color: #404; font-weight: bold; } + pre .lit, code .lit { color: #044; } + pre .pun, code .pun { color: #440; } + pre .pln, code .pln { color: #000; } + pre .tag, code .tag { color: #006; font-weight: bold; } + pre .atn, code .atn { color: #404; } + pre .atv, code .atv { color: #060; } +} diff --git a/build/AngularJS in Patterns.pdf b/build/AngularJS in Patterns.pdf deleted file mode 100644 index b6780106275c7643f6bd58e4147ed669f1995444..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 702440 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%0AJRV#jyHN$+-4at1Wjw*~ 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	>lK2 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%0D+Pt|L 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%0DFdfxSjrkf&Y@QV2FQX1S)_)|Nq92|08cHAdE;w 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 C0EK4& diff --git a/images/chain-of-responsibilities.svg b/chain-of-responsibilities.svg similarity index 100% rename from images/chain-of-responsibilities.svg rename to chain-of-responsibilities.svg diff --git a/images/command.svg b/command.svg similarity index 100% rename from images/command.svg rename to command.svg diff --git a/images/composite.svg b/composite.svg similarity index 100% rename from images/composite.svg rename to composite.svg diff --git a/images/data-mapper.svg b/data-mapper.svg similarity index 100% rename from images/data-mapper.svg rename to data-mapper.svg diff --git a/images/decorator.svg b/decorator.svg similarity index 100% rename from images/decorator.svg rename to decorator.svg diff --git a/images/facade.svg b/facade.svg similarity index 100% rename from images/facade.svg rename to facade.svg diff --git a/images/factory-method.svg b/factory-method.svg similarity index 100% rename from images/factory-method.svg rename to factory-method.svg diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 6b5e37b..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,12 +0,0 @@ -/* global require */ - -'use strict'; - -var gulp = require('gulp'); -var shell = require('gulp-shell'); - -gulp.task('default', shell.task([ - 'mkdir temp && cp -r ./README.md ./images/* temp', - './node_modules/.bin/generate-md --layout minko-book --input ./temp --output ../angularjs-in-patterns-gh-pages', - 'rm -rf temp' -])); \ No newline at end of file diff --git a/images/intercepting-filters.svg b/intercepting-filters.svg similarity index 100% rename from images/intercepting-filters.svg rename to intercepting-filters.svg diff --git a/images/interpreter.svg b/interpreter.svg similarity index 100% rename from images/interpreter.svg rename to interpreter.svg diff --git a/images/observer.svg b/observer.svg similarity index 100% rename from images/observer.svg rename to observer.svg diff --git a/package.json b/package.json deleted file mode 100644 index 6198284..0000000 --- a/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "angularjs-in-patterns", - "version": "0.0.0", - "description": "AngularJS in patterns - this repository provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git://github.com/mgechev/angularjs-patterns.git" - }, - "author": "mgechev", - "license": "MIT", - "gitHead": "2009434a6dfdbe5f06f81253fb853840af753b36", - "readmeFilename": "README.md", - "devDependencies": { - "gulp": "^3.8.10", - "markdown-styles": "https://github.com/mgechev/markdown-styles/tarball/master", - "gulp-shell": "^0.2.11" - } -} diff --git a/images/page-controller.svg b/page-controller.svg similarity index 100% rename from images/page-controller.svg rename to page-controller.svg diff --git a/images/proxy.svg b/proxy.svg similarity index 100% rename from images/proxy.svg rename to proxy.svg diff --git a/images/singleton.svg b/singleton.svg similarity index 100% rename from images/singleton.svg rename to singleton.svg diff --git a/images/template-view.svg b/template-view.svg similarity index 100% rename from images/template-view.svg rename to template-view.svg From ab214db6f5a0bd8c1a982a6b27d464f4f40c0481 Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Mon, 16 Mar 2015 14:45:50 -0700 Subject: [PATCH 02/19] Update main file --- README.html => index.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.html => index.html (100%) diff --git a/README.html b/index.html similarity index 100% rename from README.html rename to index.html From 7c4e972f0d8c5aeb7517228ba2fdad2373c63620 Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Mon, 16 Mar 2015 15:15:33 -0700 Subject: [PATCH 03/19] Update index.html --- index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.html b/index.html index 5c0f1d3..3479fe7 100644 --- a/index.html +++ b/index.html @@ -36,6 +36,7 @@ <div id="main"> <div id="container"> <div id="content" class="post"><h1 id="angularjs-in-patterns">AngularJS in Patterns</h1> +<!-- toc --> <h2 id="table-of-contents">Table of Contents</h2> <ul class="list"> <li><a href="#abstract">Abstract</a></li> @@ -81,6 +82,7 @@ <h2 id="table-of-contents">Table of Contents</h2> </li> <li><a href="#references">References</a></li> </ul> +<!-- endtoc --> <h2 id="abstract">Abstract</h2> <p>One of the best ways to learn something new is to see how the things you already know are used in it. This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. From 4cc95bc3822b714b2a175ea5de014a33a153e30a Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Mon, 16 Mar 2015 15:16:53 -0700 Subject: [PATCH 04/19] Update links --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 3479fe7..f5499e3 100644 --- a/index.html +++ b/index.html @@ -11,8 +11,8 @@ src: local('Droid Sans'), local('DroidSans'), url('DroidSans.woff') format('woff'); } </style> - <link href='http://fonts.googleapis.com/css?family=Andika|Cantarell:400,700,400italic' rel='stylesheet' type='text/css' /> - <link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css' /> + <link href='//fonts.googleapis.com/css?family=Andika|Cantarell:400,700,400italic' rel='stylesheet' type='text/css' /> + <link href='//fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css' /> <script src="assets/jquery-1.6.1.min.js"></script> <link type="text/css" rel="stylesheet" href="assets/style.css"/> <link type="text/css" rel="stylesheet" href="assets/assert.css"/> From 4b03347189c3f8cc458e6a2bebd629a196a734a8 Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Mon, 16 Mar 2015 15:29:57 -0700 Subject: [PATCH 05/19] Update gh link --- index.html | 51 +++------------------------------------------------ 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/index.html b/index.html index f5499e3..804f0af 100644 --- a/index.html +++ b/index.html @@ -24,6 +24,9 @@ <script type="text/javascript" src="assets/runner.js"></script> </head> <body> + +<a href="https://github.com/mgechev/angularjs-in-patterns"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a> + <div id="wrapper"> <div id="header"> </div> @@ -36,53 +39,6 @@ <div id="main"> <div id="container"> <div id="content" class="post"><h1 id="angularjs-in-patterns">AngularJS in Patterns</h1> -<!-- toc --> -<h2 id="table-of-contents">Table of Contents</h2> -<ul class="list"> -<li><a href="#abstract">Abstract</a></li> -<li><a href="#introduction">Introduction</a></li> -<li><a href="#angularjs-overview">AngularJS overview</a></li> -<li><a href="#partials">Partials</a></li> -<li><a href="#controllers">Controllers</a></li> -<li><a href="#scope">Scope</a></li> -<li><a href="#directives">Directives</a></li> -<li><a href="#filters">Filters</a></li> -<li><a href="#services">Services</a></li> -<li><a href="#angularjs-patterns">AngularJS Patterns</a></li> -<li><a href="#services-1">Services</a><ul class="list"> -<li><a href="#singleton">Singleton</a></li> -<li><a href="#factory-method">Factory Method</a></li> -<li><a href="#decorator">Decorator</a></li> -<li><a href="#facade">Facade</a></li> -<li><a href="#proxy">Proxy</a></li> -<li><a href="#active-record">Active Record</a></li> -<li><a href="#intercepting-filters">Intercepting Filters</a></li> -</ul> -</li> -<li><a href="#directives-1">Directives</a><ul class="list"> -<li><a href="#composite">Composite</a></li> -<li><a href="#interpreter">Interpreter</a></li> -<li><a href="#template-view">Template View</a></li> -</ul> -</li> -<li><a href="#scope-1">Scope</a><ul class="list"> -<li><a href="#observer">Observer</a></li> -<li><a href="#chain-of-responsibilities">Chain of Responsibilities</a></li> -<li><a href="#command">Command</a></li> -</ul> -</li> -<li><a href="#controller-1">Controller</a><ul class="list"> -<li><a href="#page-controller">Page Controller</a></li> -</ul> -</li> -<li><a href="#others">Others</a><ul class="list"> -<li><a href="#module-pattern">Module Pattern</a></li> -<li><a href="#data-mapper">Data Mapper</a></li> -</ul> -</li> -<li><a href="#references">References</a></li> -</ul> -<!-- endtoc --> <h2 id="abstract">Abstract</h2> <p>One of the best ways to learn something new is to see how the things you already know are used in it. This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. @@ -813,7 +769,6 @@ <h3 id="data-mapper">Data Mapper</h3> </div> <div id="sidebar"><ul class="nav nav-list"> <li><a href="#angularjs-in-patterns">AngularJS in Patterns</a></li> - <li><a href="#table-of-contents">Table of Contents</a></li> <li><a href="#abstract">Abstract</a></li> <li><a href="#introduction">Introduction</a></li> <li><a href="#angularjs-overview">AngularJS overview</a></li> From 148018912c9566536b49906bbc0377cd5a12883f Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Tue, 17 Mar 2015 10:40:32 -0700 Subject: [PATCH 06/19] Update styles --- assets/style.css | 36 ++++++++++++++++++++++++++ index.html | 66 ++++++++++++++++++++++++------------------------ 2 files changed, 69 insertions(+), 33 deletions(-) diff --git a/assets/style.css b/assets/style.css index b597dc6..9869100 100644 --- a/assets/style.css +++ b/assets/style.css @@ -271,3 +271,39 @@ div.notice { font-size: larger; margin: 8px; } + +.nav li { + margin-bottom: 6px; +} + +.heading-1 { + margin-left: 0; +} + +.heading-2 { + margin-left: 10px; +} + +.heading-3 { + margin-left: 20px; +} + +.heading-4 { + margin-left: 30px; + display: none; +} + +.heading-5 { + margin-left: 40px; + display: none; +} + +@media only screen +and (max-device-width : 667px) { + #sidebar { + display: none; + } + #container { + width: 100%; + } +} diff --git a/index.html b/index.html index 804f0af..626bce0 100644 --- a/index.html +++ b/index.html @@ -768,39 +768,39 @@ <h3 id="data-mapper">Data Mapper</h3> </div> </div> <div id="sidebar"><ul class="nav nav-list"> - <li><a href="#angularjs-in-patterns">AngularJS in Patterns</a></li> - <li><a href="#abstract">Abstract</a></li> - <li><a href="#introduction">Introduction</a></li> - <li><a href="#angularjs-overview">AngularJS overview</a></li> - <li><a href="#partials">Partials</a></li> - <li><a href="#controllers">Controllers</a></li> - <li><a href="#scope">Scope</a></li> - <li><a href="#directives">Directives</a></li> - <li><a href="#filters">Filters</a></li> - <li><a href="#services">Services</a></li> - <li><a href="#angularjs-patterns">AngularJS Patterns</a></li> - <li><a href="#services">Services</a></li> - <li><a href="#singleton">Singleton</a></li> - <li><a href="#factory-method">Factory Method</a></li> - <li><a href="#decorator">Decorator</a></li> - <li><a href="#facade">Facade</a></li> - <li><a href="#proxy">Proxy</a></li> - <li><a href="#active-record">Active Record</a></li> - <li><a href="#intercepting-filters">Intercepting Filters</a></li> - <li><a href="#directives">Directives</a></li> - <li><a href="#composite">Composite</a></li> - <li><a href="#interpreter">Interpreter</a></li> - <li><a href="#template-view">Template View</a></li> - <li><a href="#scope">Scope</a></li> - <li><a href="#observer">Observer</a></li> - <li><a href="#chain-of-responsibilities">Chain of Responsibilities</a></li> - <li><a href="#command">Command</a></li> - <li><a href="#controllers">Controllers</a></li> - <li><a href="#page-controller">Page Controller</a></li> - <li><a href="#others">Others</a></li> - <li><a href="#module-pattern">Module Pattern</a></li> - <li><a href="#data-mapper">Data Mapper</a></li> - <li><a href="#references">References</a></li> + <li><a href="#angularjs-in-patterns" class="heading heading-1">AngularJS in Patterns</a></li> + <li><a href="#abstract" class="heading heading-2">Abstract</a></li> + <li><a href="#introduction" class="heading heading-2">Introduction</a></li> + <li><a href="#angularjs-overview" class="heading heading-2">AngularJS overview</a></li> + <li><a href="#partials" class="heading heading-3">Partials</a></li> + <li><a href="#controllers" class="heading heading-3">Controllers</a></li> + <li><a href="#scope" class="heading heading-3">Scope</a></li> + <li><a href="#directives" class="heading heading-3">Directives</a></li> + <li><a href="#filters" class="heading heading-3">Filters</a></li> + <li><a href="#services" class="heading heading-3">Services</a></li> + <li><a href="#angularjs-patterns" class="heading heading-2">AngularJS Patterns</a></li> + <li><a href="#services" class="heading heading-3">Services</a></li> + <li><a href="#singleton" class="heading heading-4">Singleton</a></li> + <li><a href="#factory-method" class="heading heading-4">Factory Method</a></li> + <li><a href="#decorator" class="heading heading-4">Decorator</a></li> + <li><a href="#facade" class="heading heading-4">Facade</a></li> + <li><a href="#proxy" class="heading heading-4">Proxy</a></li> + <li><a href="#active-record" class="heading heading-4">Active Record</a></li> + <li><a href="#intercepting-filters" class="heading heading-4">Intercepting Filters</a></li> + <li><a href="#directives" class="heading heading-3">Directives</a></li> + <li><a href="#composite" class="heading heading-4">Composite</a></li> + <li><a href="#interpreter" class="heading heading-3">Interpreter</a></li> + <li><a href="#template-view" class="heading heading-4">Template View</a></li> + <li><a href="#scope" class="heading heading-3">Scope</a></li> + <li><a href="#observer" class="heading heading-4">Observer</a></li> + <li><a href="#chain-of-responsibilities" class="heading heading-4">Chain of Responsibilities</a></li> + <li><a href="#command" class="heading heading-4">Command</a></li> + <li><a href="#controllers" class="heading heading-3">Controllers</a></li> + <li><a href="#page-controller" class="heading heading-4">Page Controller</a></li> + <li><a href="#others" class="heading heading-3">Others</a></li> + <li><a href="#module-pattern" class="heading heading-4">Module Pattern</a></li> + <li><a href="#data-mapper" class="heading heading-3">Data Mapper</a></li> + <li><a href="#references" class="heading heading-2">References</a></li> </ul> </div> <div class="clear"> From 06c3be71d0c4200c515ff106f43b8627f19eb09d Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Tue, 17 Mar 2015 11:12:04 -0700 Subject: [PATCH 07/19] Fix urls --- index.html | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/index.html b/index.html index 626bce0..9c31343 100644 --- a/index.html +++ b/index.html @@ -179,7 +179,7 @@ <h4 id="singleton">Singleton</h4> <p>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.</p> </blockquote> <p>In the UML diagram bellow is illustrated the singleton design pattern.</p> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/singleton.svg" alt="Singleton" title="Fig. 1"></p> +<p class="img-container"><img src="./singleton.svg" alt="Singleton" title="Fig. 1"></p> <p>When given dependency is required by any component, AngularJS resolves it using the following algorithm:</p> <ul class="list"> <li>Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).</li> @@ -223,7 +223,7 @@ <h4 id="factory-method">Factory Method</h4> <blockquote> <p>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/factory-method.svg" alt="Factory Method" title="Fig. 2"></p> +<p class="img-container"><img src="./factory-method.svg" alt="Factory Method" title="Fig. 2"></p> <p>Lets consider the following snippet:</p> <pre class="hljs"><code>myModule.config(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$provide</span>)</span> </span>{ <span class="hljs-variable">$provide</span>.provider(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ @@ -292,7 +292,7 @@ <h4 id="decorator">Decorator</h4> <blockquote> <p>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/decorator.svg" alt="Decorator" title="Fig. 4"></p> +<p class="img-container"><img src="./decorator.svg" alt="Decorator" title="Fig. 4"></p> <p>AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method <code>decorator</code> of <code>$provide</code> you can create "wrapper" of any service you have previously defined or used by a third-party:</p> <pre class="hljs"><code>myModule.controller(<span class="hljs-string">'MainCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(foo)</span> </span>{ foo.bar(); @@ -335,7 +335,7 @@ <h4 id="facade">Facade</h4> </li> </ol> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/facade.svg" alt="Facade" title="Fig. 11"></p> +<p class="img-container"><img src="./facade.svg" alt="Facade" title="Fig. 11"></p> <p>There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.</p> <p>For example, lets take a look how we can create an <code>XMLHttpRequest</code> POST request:</p> <pre class="hljs"><code>var <span class="hljs-keyword">http</span> = new XMLHttpRequest(), @@ -370,7 +370,7 @@ <h4 id="proxy">Proxy</h4> <blockquote> <p>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/proxy.svg" alt="Proxy" title="Fig. 9"></p> +<p class="img-container"><img src="./proxy.svg" alt="Proxy" title="Fig. 9"></p> <p>We can distinguish three different types of proxy:</p> <ul class="list"> <li>Virtual Proxy</li> @@ -391,7 +391,7 @@ <h4 id="active-record">Active Record</h4> <blockquote> <p>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/active-record.svg" alt="Active Record" title="Fig. 7"></p> +<p class="img-container"><img src="./active-record.svg" alt="Active Record" title="Fig. 7"></p> <p>AngularJS defines a service called <code>$resource</code>. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.</p> <p>According to the AngularJS' documentation <code>$resource</code> is:</p> <blockquote> @@ -418,7 +418,7 @@ <h4 id="intercepting-filters">Intercepting Filters</h4> <blockquote> <p>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/intercepting-filters.svg" alt="Composite" title="Fig. 3"></p> +<p class="img-container"><img src="./intercepting-filters.svg" alt="Composite" title="Fig. 3"></p> <p>In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.</p> <p>In AngularJS we have the idea of the Intercepting Filters in <code>$httpProvider</code>. <code>$httpProvider</code> has an array property called <code>interceptors</code>, which contains a list of objects. Each object may have properties called: <code>request</code>, <code>response</code>, <code>requestError</code>, <code>responseError</code>.</p> <p><code>requestError</code> is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively <code>responseError</code> is being called when the previous <code>response</code> interceptor has thrown an error.</p> @@ -437,7 +437,7 @@ <h4 id="composite">Composite</h4> <blockquote> <p>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/composite.svg" alt="Composite" title="Fig. 3"></p> +<p class="img-container"><img src="./composite.svg" alt="Composite" title="Fig. 3"></p> <p>According to the Gang of Four, MVC is nothing more than combination of:</p> <ul class="list"> <li>Strategy</li> @@ -472,7 +472,7 @@ <h3 id="interpreter">Interpreter</h3> <blockquote> <p>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/interpreter.svg" alt="Interpreter" title="Fig. 6"></p> +<p class="img-container"><img src="./interpreter.svg" alt="Interpreter" title="Fig. 6"></p> <p>Behind its <code>$parse</code> service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:</p> <ul class="list"> @@ -523,7 +523,7 @@ <h3 id="interpreter">Interpreter</h3> <blockquote> <p>Renders information into HTML by embedding markers in an HTML page.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/template-view.svg" alt="Template View" title="Fig. 8"></p> +<p class="img-container"><img src="./template-view.svg" alt="Template View" title="Fig. 8"></p> <p>The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.</p> <p>Templates are very commonly used especially in the back-end. For example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.</p> @@ -551,7 +551,7 @@ <h4 id="observer">Observer</h4> <blockquote> <p>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg" alt="Observer" title="Fig. 7"></p> +<p class="img-container"><img src="./observer.svg" alt="Observer" title="Fig. 7"></p> <p>There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see <a href="#scope">Scope</a>). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.</p> <p>Each AngularJS scope has public methods called <code>$on</code>, <code>$emit</code> and <code>$broadcast</code>. The method <code>$on</code> accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the <code>Observer</code> interface (in JavaScript the functions are first-class, so we can provide only implementation of the <code>notify</code> method):</p> <pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExampleCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ @@ -571,7 +571,7 @@ <h4 id="chain-of-responsibilities">Chain of Responsibilities</h4> <blockquote> <p>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/chain-of-responsibilities.svg" alt="Chain of Responsibilities" title="Fig. 5"></p> +<p class="img-container"><img src="./chain-of-responsibilities.svg" alt="Chain of Responsibilities" title="Fig. 5"></p> <p>As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their <code>$parent</code> property.</p> <p>When <code>$emit</code> or <code>$broadcast</code> are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:</p> <ul class="list"> @@ -600,7 +600,7 @@ <h4 id="command">Command</h4> <blockquote> <p>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/command.svg" alt="Command" title="Fig. 11"></p> +<p class="img-container"><img src="./command.svg" alt="Command" title="Fig. 11"></p> <p>Before continuing with the application of the command pattern lets describe how AngularJS implements data binding.</p> <p>When we want to bind our model to the view we use the directives <code>ng-bind</code> (for single-way data binding) and <code>ng-model</code> (for two-way data binding). For example, if we want each change in the model <code>foo</code> to reflect the view we can:</p> <pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">span</span> <span class="hljs-attribute">ng-bind</span>=<span class="hljs-value">"foo"</span>></span><span class="hljs-tag"></<span class="hljs-title">span</span>></span></code></pre><p>Now each time we change the value of <code>foo</code> the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:</p> @@ -624,7 +624,7 @@ <h4 id="page-controller">Page Controller</h4> <blockquote> <p>An object that handles a request for a specific page or action on a Web site. Martin Fowler</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/page-controller.svg" alt="Page Controller" title="Fig. 8"></p> +<p class="img-container"><img src="./page-controller.svg" alt="Page Controller" title="Fig. 8"></p> <p>According to <a href="#references">4</a> the page controller:</p> <blockquote> <p>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code</p> @@ -700,7 +700,7 @@ <h3 id="data-mapper">Data Mapper</h3> <blockquote> <p>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.</p> </blockquote> -<p class="img-container"><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/data-mapper.svg" alt="Data Mapper" title="Fig. 10"></p> +<p class="img-container"><img src="./data-mapper.svg" alt="Data Mapper" title="Fig. 10"></p> <p>As the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).</p> <p>Usually, if we have RESTful API <code>$resource</code> will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.</p> <p>For instance, lets assume we have application in which each user has:</p> From b5476e933fd500ec6f668ad8152ae28fbc3fa4ec Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Wed, 18 Mar 2015 09:42:35 -0700 Subject: [PATCH 08/19] Update styles --- assets/style.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/assets/style.css b/assets/style.css index 9869100..1680477 100644 --- a/assets/style.css +++ b/assets/style.css @@ -298,8 +298,7 @@ div.notice { display: none; } -@media only screen -and (max-device-width : 667px) { +@media (max-device-width : 667px) { #sidebar { display: none; } From 46abaaabf3f0b165057a3d2132545619618c2fef Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Wed, 18 Mar 2015 09:56:32 -0700 Subject: [PATCH 09/19] Fix styles --- assets/style.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/style.css b/assets/style.css index 1680477..0733b47 100644 --- a/assets/style.css +++ b/assets/style.css @@ -298,11 +298,16 @@ div.notice { display: none; } -@media (max-device-width : 667px) { +@media (max-width : 980px) { #sidebar { display: none; } - #container { + #content { + float: none; + margin: auto; + width: 90%; + } + #wrapper { width: 100%; } } From ed458923798f17a9490dc85b762623740c111020 Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Wed, 18 Mar 2015 09:59:03 -0700 Subject: [PATCH 10/19] Fix styles --- assets/style.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assets/style.css b/assets/style.css index 0733b47..24a86b3 100644 --- a/assets/style.css +++ b/assets/style.css @@ -302,12 +302,18 @@ div.notice { #sidebar { display: none; } + #container, #content { float: none; + } + #content { margin: auto; width: 90%; } #wrapper { width: 100%; } + .post p { + max-width: 100%; + } } From e993a928b0cfd1a5a56a326ee1d63e7a0938b4e5 Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Mon, 30 Mar 2015 09:24:33 -0700 Subject: [PATCH 11/19] Add translations --- index.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/index.html b/index.html index 9c31343..ffd887d 100644 --- a/index.html +++ b/index.html @@ -39,6 +39,11 @@ <div id="main"> <div id="container"> <div id="content" class="post"><h1 id="angularjs-in-patterns">AngularJS in Patterns</h1> +<h2 id="translations">Translations</h2> +<ul class="list"> +<li><a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/README-ja-jp.md">Japanese Translation</a> by <a href="https://twitter.com/morizotter">morizotter</a></li> +<li><a href="http://habrahabr.ru/post/250149/">Russian Translation</a></li> +</ul> <h2 id="abstract">Abstract</h2> <p>One of the best ways to learn something new is to see how the things you already know are used in it. This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. @@ -769,6 +774,7 @@ <h3 id="data-mapper">Data Mapper</h3> </div> <div id="sidebar"><ul class="nav nav-list"> <li><a href="#angularjs-in-patterns" class="heading heading-1">AngularJS in Patterns</a></li> + <li><a href="#translations" class="heading heading-2">Translations</a></li> <li><a href="#abstract" class="heading heading-2">Abstract</a></li> <li><a href="#introduction" class="heading heading-2">Introduction</a></li> <li><a href="#angularjs-overview" class="heading heading-2">AngularJS overview</a></li> From a3c092772bbfd3f717ee45478206cf47ba1a7a16 Mon Sep 17 00:00:00 2001 From: mgechev <mgechev@gmail.com> Date: Thu, 23 Jul 2015 17:52:34 +0300 Subject: [PATCH 12/19] Update index --- index.html | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index ffd887d..7164d9e 100644 --- a/index.html +++ b/index.html @@ -41,8 +41,9 @@ <div id="content" class="post"><h1 id="angularjs-in-patterns">AngularJS in Patterns</h1> <h2 id="translations">Translations</h2> <ul class="list"> -<li><a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/README-ja-jp.md">Japanese Translation</a> by <a href="https://twitter.com/morizotter">morizotter</a></li> +<li><a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md">Japanese Translation</a> by <a href="https://twitter.com/morizotter">morizotter</a></li> <li><a href="http://habrahabr.ru/post/250149/">Russian Translation</a></li> +<li><a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md">French Translation</a> by <a href="https://github.com/manekinekko">manekinekko</a></li> </ul> <h2 id="abstract">Abstract</h2> <p>One of the best ways to learn something new is to see how the things you already know are used in it. @@ -172,7 +173,7 @@ <h3 id="filters">Filters</h3> } }; });</code></pre><p>The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyCtrl</span><span class="hljs-params">(developer)</span> </span>{ +<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyCtrl</span><span class="hljs-params">(Developer)</span> </span>{ <span class="hljs-keyword">var</span> developer = <span class="hljs-keyword">new</span> Developer(); developer.live(); }</code></pre><h2 id="angularjs-patterns">AngularJS Patterns</h2> @@ -572,6 +573,7 @@ <h4 id="observer">Observer</h4> <p>Analogical is the case when the method <code>$broadcast</code> is called. The only difference is that the event would be transmitted downwards - to all children scopes. Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).</p> <p>In the JavaScript community this pattern is better known as publish/subscribe.</p> +<p>For a best practice example see <a href="#observer-pattern-as-an-external-service">Observer Pattern as an External Service</a></p> <h4 id="chain-of-responsibilities">Chain of Responsibilities</h4> <blockquote> <p>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.</p> @@ -758,7 +760,53 @@ <h3 id="data-mapper">Data Mapper</h3> <span class="hljs-tag"><<span class="hljs-title">li</span> <span class="hljs-attribute">ng-repeat</span>=<span class="hljs-value">"friend in user.friends"</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">friend</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">li</span>></span> <span class="hljs-tag"></<span class="hljs-title">ul</span>></span> <span class="hljs-tag"></<span class="hljs-title">div</span>></span> -<span class="hljs-tag"></<span class="hljs-title">div</span>></span></span></code></pre><h2 id="references">References</h2> +<span class="hljs-tag"></<span class="hljs-title">div</span>></span></span></code></pre><h3 id="observer-pattern-as-an-external-service">Observer Pattern as an External Service</h3> +<h5 id="about">About</h5> +<p>Below is an example taken from <a href="https://github.com/greglbd/angular-observer-pattern">here</a>. This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that <code>$scope.$watch</code> and more specific to a unique scope or object than $emit and $broadcast when used correctly.</p> +<p><strong>Use Case:</strong> You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.</p> +<h5 id="controller-example">Controller Example</h5> +<p>Below example shows how to attach, notify and detach an event.</p> +<pre class="hljs"><code>angular.module(<span class="hljs-string">'app.controllers'</span>) + .controller(<span class="hljs-string">'ObserverExample'</span>, ObserverExample); +ObserverExample.<span class="hljs-variable">$inject</span>= [<span class="hljs-string">'ObserverService'</span>, <span class="hljs-string">'$timeout'</span>]; + +<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ObserverExample</span><span class="hljs-params">(ObserverService, <span class="hljs-variable">$timeout</span>)</span> </span>{ + <span class="hljs-keyword">var</span> vm = this; + <span class="hljs-keyword">var</span> id = <span class="hljs-string">'vm1'</span>; + + ObserverService.attach(callbackFunction, <span class="hljs-string">'let_me_know'</span>, id) + + <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callbackFunction</span><span class="hljs-params">(params)</span></span>{ + console.log(<span class="hljs-string">'now i know'</span>); + ObserverService.detachByEvent(<span class="hljs-string">'let_me_know'</span>) + } + + <span class="hljs-variable">$timeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{ + ObserverService.notify(<span class="hljs-string">'let_me_know'</span>); + }, <span class="hljs-number">5000</span>); +}</code></pre><p>Alternative way to remove event</p> +<pre class="hljs"><code>angular.module(<span class="hljs-string">'app.controllers'</span>) + .controller(<span class="hljs-string">'ObserverExample'</span>, ObserverExample); +ObserverExample.<span class="hljs-variable">$inject</span>= [<span class="hljs-string">'ObserverService'</span>, <span class="hljs-string">'$timeout'</span>, <span class="hljs-string">'$scope'</span>]; + +<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ObserverExample</span><span class="hljs-params">(ObserverService, <span class="hljs-variable">$timeout</span>, <span class="hljs-variable">$scope</span>)</span> </span>{ + <span class="hljs-keyword">var</span> vm = this; + <span class="hljs-keyword">var</span> id = <span class="hljs-string">'vm1'</span>; + ObserverService.attach(callbackFunction, <span class="hljs-string">'let_me_know'</span>, id) + + <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callbackFunction</span><span class="hljs-params">(params)</span></span>{ + console.log(<span class="hljs-string">'now i know'</span>); + } + + <span class="hljs-variable">$timeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{ + ObserverService.notify(<span class="hljs-string">'let_me_know'</span>); + }, <span class="hljs-number">5000</span>); + + <span class="hljs-comment">// Cleanup listeners when this controller is destroyed</span> + <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'$destroy'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span><span class="hljs-params">()</span> </span>{ + ObserverService.detachByEvent(<span class="hljs-string">'let_me_know'</span>) + }); +}</code></pre><h2 id="references">References</h2> <ol class="list"> <li><a href="https://en.wikipedia.org/wiki">Wikipedia</a>. The source of all brief descriptions of the design patterns is wikipedia.</li> <li><a href="https://docs.angularjs.org">AngularJS' documentation</a></li> @@ -806,6 +854,9 @@ <h3 id="data-mapper">Data Mapper</h3> <li><a href="#others" class="heading heading-3">Others</a></li> <li><a href="#module-pattern" class="heading heading-4">Module Pattern</a></li> <li><a href="#data-mapper" class="heading heading-3">Data Mapper</a></li> + <li><a href="#observer-pattern-as-an-external-service" class="heading heading-3">Observer Pattern as an External Service</a></li> + <li><a href="#about" class="heading heading-5">About</a></li> + <li><a href="#controller-example" class="heading heading-5">Controller Example</a></li> <li><a href="#references" class="heading heading-2">References</a></li> </ul> </div> From d2bb5b389996129c66ba62d84f6c1c16f4d8487f Mon Sep 17 00:00:00 2001 From: Minko Gechev <mgechev@gmail.com> Date: Tue, 1 Sep 2015 16:57:19 +0300 Subject: [PATCH 13/19] Create gh-pages branch via GitHub --- index.html | 1510 +++++++++++++++++++++------------- params.json | 1 + stylesheets/github-light.css | 116 +++ stylesheets/normalize.css | 424 ++++++++++ stylesheets/stylesheet.css | 245 ++++++ 5 files changed, 1735 insertions(+), 561 deletions(-) create mode 100644 params.json create mode 100644 stylesheets/github-light.css create mode 100644 stylesheets/normalize.css create mode 100644 stylesheets/stylesheet.css diff --git a/index.html b/index.html index 7164d9e..848b751 100644 --- a/index.html +++ b/index.html @@ -1,871 +1,1259 @@ <!DOCTYPE html> -<html> +<html lang="en-us"> <head> - <title>AngularJS in Patterns</title> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <style type="text/css"> - @font-face { - font-family: 'Droid Sans'; - font-style: normal; - font-weight: normal; - src: local('Droid Sans'), local('DroidSans'), url('DroidSans.woff') format('woff'); - } - </style> - <link href='//fonts.googleapis.com/css?family=Andika|Cantarell:400,700,400italic' rel='stylesheet' type='text/css' /> - <link href='//fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css' /> - <script src="assets/jquery-1.6.1.min.js"></script> - <link type="text/css" rel="stylesheet" href="assets/style.css"/> - <link type="text/css" rel="stylesheet" href="assets/assert.css"/> - <link type="text/css" rel="stylesheet" href="assets/prettify.css"/> - <link type="text/css" rel="stylesheet" href="assets/hljs-github.min.css"/> - - <script type="text/javascript" src="assets/prettify.js"></script> - <!-- Script runner --> - <script type="text/javascript" src="assets/runner.js"></script> + <meta charset="UTF-8"> + <title>AngularJS in Patterns by mgechev</title> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen"> + <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'> + <link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen"> + <link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen"> </head> -<body> + <body> + <section class="page-header"> + <h1 class="project-name">AngularJS in Patterns</h1> + <h2 class="project-tagline">"AngularJS in Patterns" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.</h2> + <a href="https://github.com/mgechev/angularjs-in-patterns" class="btn">View on GitHub</a> + <a href="https://github.com/mgechev/angularjs-in-patterns/zipball/master" class="btn">Download .zip</a> + <a href="https://github.com/mgechev/angularjs-in-patterns/tarball/master" class="btn">Download .tar.gz</a> + </section> + + <section class="main-content"> + <h1> +<a id="angularjs-in-patterns" class="anchor" href="#angularjs-in-patterns" aria-hidden="true"><span class="octicon octicon-link"></span></a>AngularJS in Patterns</h1> + + + +<h2> +<a id="table-of-contents" class="anchor" href="#table-of-contents" aria-hidden="true"><span class="octicon octicon-link"></span></a>Table of Contents</h2> + +<ul> +<li><a href="#translations">Translations</a></li> +<li><a href="#abstract">Abstract</a></li> +<li><a href="#introduction">Introduction</a></li> +<li> +<a href="#angularjs-overview">AngularJS overview</a> + +<ul> +<li><a href="#partials">Partials</a></li> +<li><a href="#controllers">Controllers</a></li> +<li><a href="#scope">Scope</a></li> +<li><a href="#directives">Directives</a></li> +<li><a href="#filters">Filters</a></li> +<li><a href="#services">Services</a></li> +</ul> +</li> +<li> +<a href="#angularjs-patterns">AngularJS Patterns</a> + +<ul> +<li> +<a href="#services-1">Services</a> + +<ul> +<li><a href="#singleton">Singleton</a></li> +<li><a href="#factory-method">Factory Method</a></li> +<li><a href="#decorator">Decorator</a></li> +<li><a href="#facade">Facade</a></li> +<li><a href="#proxy">Proxy</a></li> +<li><a href="#active-record">Active Record</a></li> +<li><a href="#intercepting-filters">Intercepting Filters</a></li> +</ul> +</li> +<li> +<a href="#directives-1">Directives</a> + +<ul> +<li><a href="#composite">Composite</a></li> +</ul> +</li> +<li> +<a href="#interpreter">Interpreter</a> + +<ul> +<li><a href="#template-view">Template View</a></li> +</ul> +</li> +<li> +<a href="#scope-1">Scope</a> + +<ul> +<li><a href="#observer">Observer</a></li> +<li><a href="#chain-of-responsibilities">Chain of Responsibilities</a></li> +<li><a href="#command">Command</a></li> +</ul> +</li> +<li> +<a href="#controller-1">Controller</a> + +<ul> +<li><a href="#page-controller">Page Controller</a></li> +</ul> +</li> +<li> +<a href="#others">Others</a> + +<ul> +<li><a href="#module-pattern">Module Pattern</a></li> +<li><a href="#data-mapper">Data Mapper</a></li> +<li><a href="#observer-pattern-as-an-external-service">Observer Pattern as an External Service</a></li> +</ul> +</li> +</ul> +</li> +<li><a href="#references">References</a></li> +</ul> -<a href="https://github.com/mgechev/angularjs-in-patterns"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a> - <div id="wrapper"> - <div id="header"> - </div> - <div class="clear"> - <hr> - </div> - <!-- Main --> +<h2> +<a id="translations" class="anchor" href="#translations" aria-hidden="true"><span class="octicon octicon-link"></span></a>Translations</h2> - <div id="main"> - <div id="container"> - <div id="content" class="post"><h1 id="angularjs-in-patterns">AngularJS in Patterns</h1> -<h2 id="translations">Translations</h2> -<ul class="list"> -<li><a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md">Japanese Translation</a> by <a href="https://twitter.com/morizotter">morizotter</a></li> +<ul> +<li> +<a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md">Japanese Translation</a> by <a href="https://twitter.com/morizotter">morizotter</a> +</li> <li><a href="http://habrahabr.ru/post/250149/">Russian Translation</a></li> -<li><a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md">French Translation</a> by <a href="https://github.com/manekinekko">manekinekko</a></li> +<li> +<a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md">French Translation</a> by <a href="https://github.com/manekinekko">manekinekko</a> +</li> </ul> -<h2 id="abstract">Abstract</h2> + +<h2> +<a id="abstract" class="anchor" href="#abstract" aria-hidden="true"><span class="octicon octicon-link"></span></a>Abstract</h2> + <p>One of the best ways to learn something new is to see how the things you already know are used in it. This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. The goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.</p> -<h2 id="introduction">Introduction</h2> + +<h2> +<a id="introduction" class="anchor" href="#introduction" aria-hidden="true"><span class="octicon octicon-link"></span></a>Introduction</h2> + <p>The document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.</p> + <p>The last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.</p> -<h2 id="angularjs-overview">AngularJS overview</h2> + +<h2> +<a id="angularjs-overview" class="anchor" href="#angularjs-overview" aria-hidden="true"><span class="octicon octicon-link"></span></a>AngularJS overview</h2> + <p>AngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA). SPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand. Since most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:</p> -<ul class="list"> + +<ul> <li>two-way data binding</li> <li>dependency injection</li> <li>separation of concerns</li> <li>testability</li> <li>abstraction</li> </ul> + <p>The separation of concerns is achieved by dividing each AngularJS application into separate components, such as:</p> -<ul class="list"> + +<ul> <li>partials</li> <li>controllers</li> <li>directives</li> <li>services</li> <li>filters</li> </ul> -<p>These components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.</p> -<h3 id="partials">Partials</h3> -<p>The partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).</p> + +<p>These components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.</p> + +<h3> +<a id="partials" class="anchor" href="#partials" aria-hidden="true"><span class="octicon octicon-link"></span></a>Partials</h3> + +<p>The partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).</p> + <p>Initially each SPA loads <code>index.html</code> file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.</p> + <p><strong>Sample partial</strong></p> -<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">html</span> <span class="hljs-attribute">ng-app</span>></span> - <span class="hljs-comment"><!-- Body tag augmented with ngController directive --></span> - <span class="hljs-tag"><<span class="hljs-title">body</span> <span class="hljs-attribute">ng-controller</span>=<span class="hljs-value">"MyController"</span>></span> - <span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">ng-model</span>=<span class="hljs-value">"foo"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"bar"</span>></span> - <span class="hljs-comment"><!-- Button tag with ng-click directive, and - string expression 'buttonText' - wrapped in "</span></span><span class="hljs-expression">{{ }}</span><span class="xml"><span class="hljs-comment">" markup --></span> - <span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">ng-click</span>=<span class="hljs-value">"changeFoo()"</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">buttonText</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">button</span>></span> - <span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"angular.js"</span>></span><span class="javascript"></span><span class="hljs-tag"></<span class="hljs-title">script</span>></span> - <span class="hljs-tag"></<span class="hljs-title">body</span>></span> -<span class="hljs-tag"></<span class="hljs-title">html</span>></span></span></code></pre><p>With AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute <code>ng-click</code> states that the method <code>changeFoo</code> of the current <em>scope</em> will be invoked.</p> -<h3 id="controllers">Controllers</h3> + +<div class="highlight highlight-HTML"><pre><<span class="pl-ent">html</span> <span class="pl-e">ng-app</span>> + <span class="pl-c"><!-- Body tag augmented with ngController directive --></span> + <<span class="pl-ent">body</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>MyController<span class="pl-pds">"</span></span>> + <<span class="pl-ent">input</span> <span class="pl-e">ng-model</span>=<span class="pl-s"><span class="pl-pds">"</span>foo<span class="pl-pds">"</span></span> <span class="pl-e">value</span>=<span class="pl-s"><span class="pl-pds">"</span>bar<span class="pl-pds">"</span></span>> + <span class="pl-c"><!-- Button tag with ng-click directive, and</span> +<span class="pl-c"> string expression 'buttonText'</span> +<span class="pl-c"> wrapped in "{{ }}" markup --></span> + <<span class="pl-ent">button</span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>changeFoo()<span class="pl-pds">"</span></span>>{{buttonText}}</<span class="pl-ent">button</span>> +<span class="pl-s1"> <<span class="pl-ent">script</span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>angular.js<span class="pl-pds">"</span></span>></<span class="pl-ent">script</span>></span> + </<span class="pl-ent">body</span>> +</<span class="pl-ent">html</span>></pre></div> + +<p>With AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute <code>ng-click</code> states that the method <code>changeFoo</code> of the current <em>scope</em> will be invoked.</p> + +<h3> +<a id="controllers" class="anchor" href="#controllers" aria-hidden="true"><span class="octicon octicon-link"></span></a>Controllers</h3> + <p>The AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the <em>scope</em>. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the <em>model</em> to the partials by attaching data to the <em>scope</em>. We can think of this data as <em>view model</em>.</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyController</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-variable">$scope</span>.buttonText = <span class="hljs-string">'Click me to change foo!'</span>; - <span class="hljs-variable">$scope</span>.foo = <span class="hljs-number">42</span>; - <span class="hljs-variable">$scope</span>.changeFoo = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-variable">$scope</span>.foo += <span class="hljs-number">1</span>; - alert(<span class="hljs-string">'Foo changed'</span>); +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MyController</span>(<span class="pl-smi">$scope</span>) { + $scope.<span class="pl-c1">buttonText</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Click me to change foo!<span class="pl-pds">'</span></span>; + $scope.<span class="pl-c1">foo</span> <span class="pl-k">=</span> <span class="pl-c1">42</span>; + + <span class="pl-c1">$scope</span>.<span class="pl-en">changeFoo</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { + $scope.<span class="pl-c1">foo</span> <span class="pl-k">+=</span> <span class="pl-c1">1</span>; + <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>Foo changed<span class="pl-pds">'</span></span>); }; -}</code></pre><p>For example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.</p> -<ol class="list"> +}</pre></div> + +<p>For example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.</p> + +<ol> <li>Change the value of <code>foo</code> by typing in the input box. This will immediately reflect the value of <code>foo</code> because of the two-way data binding.</li> <li>Change the value of <code>foo</code> by clicking the button, which will be labeled <code>Click me to change foo!</code>.</li> </ol> + <p>All the custom elements, attributes, comments or classes could be recognized as AngularJS <em>directives</em> if they are previously defined as ones.</p> -<h3 id="scope">Scope</h3> + +<h3> +<a id="scope" class="anchor" href="#scope" aria-hidden="true"><span class="octicon octicon-link"></span></a>Scope</h3> + <p>In AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate <em>directives</em>, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.</p> + <p>Another important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as <em>isolated</em>). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.</p> + <p>Scope inheritance is illustrated in the following example:</p> -<pre class="hljs"><code><<span class="hljs-keyword">div</span> ng-controller=<span class="hljs-string">"BaseCtrl"</span>> - <<span class="hljs-keyword">div</span> id=<span class="hljs-string">"child"</span> ng-controller=<span class="hljs-string">"ChildCtrl"</span>> - <button id=<span class="hljs-string">"parent-method"</span> ng-click=<span class="hljs-string">"foo()"</span>><span class="hljs-type">Parent</span> <span class="hljs-keyword">method</span></button> - <button ng-click=<span class="hljs-string">"bar()"</span>><span class="hljs-type">Child</span> <span class="hljs-keyword">method</span></button> - </<span class="hljs-keyword">div</span>> -</<span class="hljs-keyword">div</span>></code></pre><pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BaseCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-variable">$scope</span>.foo = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - alert(<span class="hljs-string">'Base foo'</span>); + +<div class="highlight highlight-HTML"><pre><<span class="pl-ent">div</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>BaseCtrl<span class="pl-pds">"</span></span>> + <<span class="pl-ent">div</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>child<span class="pl-pds">"</span></span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>ChildCtrl<span class="pl-pds">"</span></span>> + <<span class="pl-ent">button</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>parent-method<span class="pl-pds">"</span></span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>foo()<span class="pl-pds">"</span></span>>Parent method</<span class="pl-ent">button</span>> + <<span class="pl-ent">button</span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>bar()<span class="pl-pds">"</span></span>>Child method</<span class="pl-ent">button</span>> + </<span class="pl-ent">div</span>> +</<span class="pl-ent">div</span>></pre></div> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">BaseCtrl</span>(<span class="pl-smi">$scope</span>) { + <span class="pl-c1">$scope</span>.<span class="pl-en">foo</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { + <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>Base foo<span class="pl-pds">'</span></span>); }; } -<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ChildCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-variable">$scope</span>.bar = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - alert(<span class="hljs-string">'Child bar'</span>); +<span class="pl-k">function</span> <span class="pl-en">ChildCtrl</span>(<span class="pl-smi">$scope</span>) { + <span class="pl-c1">$scope</span>.<span class="pl-en">bar</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { + <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>Child bar<span class="pl-pds">'</span></span>); }; -}</code></pre><p>With <code>div#child</code> is associated <code>ChildCtrl</code> but since the scope injected inside <code>ChildCtrl</code> inherits prototypically from its parent scope (i.e. the one injected inside <code>BaseCtrl</code>) the method <code>foo</code> is accessible by <code>button#parent-method</code>.</p> -<h3 id="directives">Directives</h3> -<p>In AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new direcrive or consider refactoring of already existing one, which could handle the required DOM manipulations. +}</pre></div> + +<p>With <code>div#child</code> is associated <code>ChildCtrl</code> but since the scope injected inside <code>ChildCtrl</code> inherits prototypically from its parent scope (i.e. the one injected inside <code>BaseCtrl</code>) the method <code>foo</code> is accessible by <code>button#parent-method</code>.</p> + +<h3> +<a id="directives" class="anchor" href="#directives" aria-hidden="true"><span class="octicon octicon-link"></span></a>Directives</h3> + +<p>In AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations. Each directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of <em>postLink</em> function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:</p> -<ul class="list"> + +<ul> <li>template</li> <li>compile function</li> <li>link function</li> <li>etc...</li> </ul> + <p>By citing the name of the directives they can be used inside the declarative partials.</p> + <p>Example:</p> -<pre class="hljs"><code>myModule.directive(<span class="hljs-string">'alertButton'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-keyword">return</span> { - template: <span class="hljs-string">'<button ng-transclude></button>'</span>, - scope: { - content: <span class="hljs-string">'@'</span> + +<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">directive</span>(<span class="pl-s"><span class="pl-pds">'</span>alertButton<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { + <span class="pl-k">return</span> { + template<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span><button ng-transclude></button><span class="pl-pds">'</span></span>, + scope<span class="pl-k">:</span> { + content<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>@<span class="pl-pds">'</span></span> }, - replace: <span class="hljs-literal">true</span>, - restrict: <span class="hljs-string">'E'</span>, - transclude: <span class="hljs-literal">true</span>, - link: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(scope, el)</span> </span>{ - el.click(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - alert(scope.content); + replace<span class="pl-k">:</span> <span class="pl-c1">true</span>, + restrict<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>E<span class="pl-pds">'</span></span>, + transclude<span class="pl-k">:</span> <span class="pl-c1">true</span>, + <span class="pl-en">link</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span class="pl-smi">scope</span>, <span class="pl-smi">el</span>) { + el.<span class="pl-c1">click</span>(<span class="pl-k">function</span> () { + <span class="pl-c1">alert</span>(scope.<span class="pl-c1">content</span>); }); } }; -});</code></pre><pre class="hljs"><code><alert-<span class="hljs-tag">button</span> <span class="hljs-attribute">content</span>=<span class="hljs-string">"42"</span>>Click me</alert-button></code></pre><p>In the example above the tag <code><alert-button></alert-button></code> will be replaced button element. When the user clicks on the button the string <code>42</code> will be alerted.</p> +});</pre></div> + +<div class="highlight highlight-HTML"><pre><<span class="pl-ent">alert</span><span class="pl-e">-button</span> <span class="pl-e">content</span>=<span class="pl-s"><span class="pl-pds">"</span>42<span class="pl-pds">"</span></span>>Click me</<span class="pl-ent">alert</span><span class="pl-e">-button</span>></pre></div> + +<p>In the example above the tag <code><alert-button></alert-button></code> will be replaced button element. When the user clicks on the button the string <code>42</code> will be alerted.</p> + <p>Since the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.</p> -<h3 id="filters">Filters</h3> + +<h3> +<a id="filters" class="anchor" href="#filters" aria-hidden="true"><span class="octicon octicon-link"></span></a>Filters</h3> + <p>The filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, <em>services</em> and other filters through Dependency Injection.</p> + <p>Here is a definition of a sample filter, which changes the given string to uppercase:</p> -<pre class="hljs"><code>myModule.filter(<span class="hljs-string">'uppercase'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(str)</span> </span>{ - <span class="hljs-keyword">return</span> (str || <span class="hljs-string">''</span>).toUpperCase(); + +<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">filter</span>(<span class="pl-s"><span class="pl-pds">'</span>uppercase<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { + <span class="pl-k">return</span> <span class="pl-k">function</span> (<span class="pl-smi">str</span>) { + <span class="pl-k">return</span> (str <span class="pl-k">||</span> <span class="pl-s"><span class="pl-pds">'</span><span class="pl-pds">'</span></span>).<span class="pl-c1">toUpperCase</span>(); }; -});</code></pre><p>Inside a partial this filter could be used using the Unix's piping syntax:</p> -<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span></span><span class="hljs-expression">{{ <span class="hljs-variable">name</span> | <span class="hljs-variable">uppercase</span> }}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">div</span>></span></span></code></pre><p>Inside a controller the filter could be used as follows:</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyCtrl</span><span class="hljs-params">(uppercaseFilter)</span> </span>{ - <span class="hljs-variable">$scope</span>.name = uppercaseFilter(<span class="hljs-string">'foo'</span>); <span class="hljs-comment">//FOO</span> -}</code></pre><h3 id="services">Services</h3> -<p>Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service.</p> -<pre class="hljs"><code>myModule.service(<span class="hljs-string">'Developer'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-keyword">this</span>.name = <span class="hljs-string">'Foo'</span>; - <span class="hljs-keyword">this</span>.motherLanguage = <span class="hljs-string">'JavaScript'</span>; - <span class="hljs-keyword">this</span>.live = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) { - <span class="hljs-keyword">this</span>.code(); +});</pre></div> + +<p>Inside a partial this filter could be used using the Unix's piping syntax:</p> + +<div class="highlight highlight-HTML"><pre><<span class="pl-ent">div</span>>{{ name | uppercase }}</<span class="pl-ent">div</span>></pre></div> + +<p>Inside a controller the filter could be used as follows:</p> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MyCtrl</span>(<span class="pl-smi">uppercaseFilter</span>) { + $scope.<span class="pl-c1">name</span> <span class="pl-k">=</span> <span class="pl-c1">uppercaseFilter</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>); <span class="pl-c">//FOO</span> +}</pre></div> + +<h3> +<a id="services" class="anchor" href="#services" aria-hidden="true"><span class="octicon octicon-link"></span></a>Services</h3> + +<p>Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service.</p> + +<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">service</span>(<span class="pl-s"><span class="pl-pds">'</span>Developer<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { + <span class="pl-v">this</span>.<span class="pl-c1">name</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Foo<span class="pl-pds">'</span></span>; + <span class="pl-v">this</span>.<span class="pl-c1">motherLanguage</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>JavaScript<span class="pl-pds">'</span></span>; + <span class="pl-c1">this</span>.<span class="pl-en">live</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { + <span class="pl-k">while</span> (<span class="pl-c1">true</span>) { + <span class="pl-v">this</span>.<span class="pl-c1">code</span>(); } }; -});</code></pre><p>The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyCtrl</span><span class="hljs-params">(Developer)</span> </span>{ - <span class="hljs-keyword">var</span> developer = <span class="hljs-keyword">new</span> Developer(); - developer.live(); -}</code></pre><h2 id="angularjs-patterns">AngularJS Patterns</h2> +});</pre></div> + +<p>The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).</p> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MyCtrl</span>(<span class="pl-smi">Developer</span>) { + <span class="pl-k">var</span> developer <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Developer</span>(); + developer.<span class="pl-c1">live</span>(); +}</pre></div> + +<h2> +<a id="angularjs-patterns" class="anchor" href="#angularjs-patterns" aria-hidden="true"><span class="octicon octicon-link"></span></a>AngularJS Patterns</h2> + <p>In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.</p> + <p>In the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.</p> -<h3 id="services">Services</h3> -<h4 id="singleton">Singleton</h4> + +<h3> +<a id="services-1" class="anchor" href="#services-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Services</h3> + +<h4> +<a id="singleton" class="anchor" href="#singleton" aria-hidden="true"><span class="octicon octicon-link"></span></a>Singleton</h4> + <blockquote> <p>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.</p> </blockquote> + <p>In the UML diagram bellow is illustrated the singleton design pattern.</p> -<p class="img-container"><img src="./singleton.svg" alt="Singleton" title="Fig. 1"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/singleton.svg" alt="Singleton" title="Fig. 1"></p> + <p>When given dependency is required by any component, AngularJS resolves it using the following algorithm:</p> -<ul class="list"> + +<ul> <li>Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).</li> <li>If the dependency exists AngularJS pass it as parameter to the component, which requires it.</li> -<li>If the dependency does not exists:<ul class="list"> +<li>If the dependency does not exists: + +<ul> <li>AngularJS instantiate it by calling the factory method of its provider (i.e. <code>$get</code>). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.</li> <li>AngularJS caches it inside the hash map mentioned above.</li> <li>AngularJS passes it as parameter to the component, which requires it.</li> </ul> </li> </ul> -<p>We can take better look at the AngularJS' source code, which implements the method <code>getService</code>:</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getService</span><span class="hljs-params">(serviceName)</span> </span>{ - <span class="hljs-keyword">if</span> (cache.hasOwnProperty(serviceName)) { - <span class="hljs-keyword">if</span> (cache[serviceName] === INSTANTIATING) { - <span class="hljs-keyword">throw</span> $injectorMinErr(<span class="hljs-string">'cdep'</span>, <span class="hljs-string">'Circular dependency found: {0}'</span>, path.join(<span class="hljs-string">' <- '</span>)); + +<p>We can take better look at the AngularJS' source code, which implements the method <code>getService</code>:</p> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">getService</span>(<span class="pl-smi">serviceName</span>) { + <span class="pl-k">if</span> (cache.<span class="pl-c1">hasOwnProperty</span>(serviceName)) { + <span class="pl-k">if</span> (cache[serviceName] <span class="pl-k">===</span> <span class="pl-c1">INSTANTIATING</span>) { + <span class="pl-k">throw</span> $<span class="pl-c1">injectorMinErr</span>(<span class="pl-s"><span class="pl-pds">'</span>cdep<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>Circular dependency found: {0}<span class="pl-pds">'</span></span>, path.<span class="pl-c1">join</span>(<span class="pl-s"><span class="pl-pds">'</span> <- <span class="pl-pds">'</span></span>)); } - <span class="hljs-keyword">return</span> cache[serviceName]; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">try</span> { - path.unshift(serviceName); - cache[serviceName] = INSTANTIATING; - <span class="hljs-keyword">return</span> cache[serviceName] = factory(serviceName); - } <span class="hljs-keyword">catch</span> (err) { - <span class="hljs-keyword">if</span> (cache[serviceName] === INSTANTIATING) { - <span class="hljs-keyword">delete</span> cache[serviceName]; + <span class="pl-k">return</span> cache[serviceName]; + } <span class="pl-k">else</span> { + <span class="pl-k">try</span> { + path.<span class="pl-c1">unshift</span>(serviceName); + cache[serviceName] <span class="pl-k">=</span> <span class="pl-c1">INSTANTIATING</span>; + <span class="pl-k">return</span> cache[serviceName] <span class="pl-k">=</span> <span class="pl-c1">factory</span>(serviceName); + } <span class="pl-k">catch</span> (err) { + <span class="pl-k">if</span> (cache[serviceName] <span class="pl-k">===</span> <span class="pl-c1">INSTANTIATING</span>) { + <span class="pl-k">delete</span> cache[serviceName]; } - <span class="hljs-keyword">throw</span> err; - } <span class="hljs-keyword">finally</span> { - path.shift(); + <span class="pl-k">throw</span> err; + } <span class="pl-k">finally</span> { + path.<span class="pl-c1">shift</span>(); } } -}</code></pre><p>We can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as <code>cache</code>).</p> +}</pre></div> + +<p>We can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as <code>cache</code>).</p> + <p>This way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:</p> -<ul class="list"> + +<ul> <li>It improves the testability of your source code</li> <li>You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)</li> </ul> -<p>For further discussion on this topic Misko Hevery's <a href="http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html">article</a> in the Google Testing blog could be considered.</p> -<h4 id="factory-method">Factory Method</h4> + +<p>For further discussion on this topic Misko Hevery's <a href="http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html">article</a> in the Google Testing blog could be considered.</p> + +<h4> +<a id="factory-method" class="anchor" href="#factory-method" aria-hidden="true"><span class="octicon octicon-link"></span></a>Factory Method</h4> + <blockquote> <p>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.</p> </blockquote> -<p class="img-container"><img src="./factory-method.svg" alt="Factory Method" title="Fig. 2"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/factory-method.svg" alt="Factory Method" title="Fig. 2"></p> + <p>Lets consider the following snippet:</p> -<pre class="hljs"><code>myModule.config(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$provide</span>)</span> </span>{ - <span class="hljs-variable">$provide</span>.provider(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-keyword">var</span> baz = <span class="hljs-number">42</span>; - <span class="hljs-keyword">return</span> { - <span class="hljs-comment">//Factory method</span> - <span class="hljs-variable">$get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(bar)</span> </span>{ - <span class="hljs-keyword">var</span> baz = bar.baz(); - <span class="hljs-keyword">return</span> { - baz: baz + +<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">config</span>(<span class="pl-k">function</span> (<span class="pl-smi">$provide</span>) { + $provide.<span class="pl-c1">provider</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { + <span class="pl-k">var</span> baz <span class="pl-k">=</span> <span class="pl-c1">42</span>; + <span class="pl-k">return</span> { + <span class="pl-c">//Factory method</span> + $<span class="pl-en">get</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span class="pl-smi">bar</span>) { + <span class="pl-k">var</span> baz <span class="pl-k">=</span> bar.<span class="pl-c1">baz</span>(); + <span class="pl-k">return</span> { + baz<span class="pl-k">:</span> baz }; } }; }); -});</code></pre><p>In the code above we use the <code>config</code> callback in order to define new "provider". Provider is an object, which has a method called <code>$get</code>. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.</p> -<p>Each service, filter, directive and controller has a provider (i.e. object which factory method, called <code>$get</code>), which is responsible for creating the component's instance.</p> -<p>We can dig a little bit deeper in AngularJS' implementation:</p> -<pre class="hljs"><code>//<span class="hljs-keyword">...</span> - -createInternalInjector(instanceCache, <span class="hljs-keyword">function</span>(servicename) { - var provider = providerInjector.get(servicename + providerSuffix); - <span class="hljs-keyword">return</span> instanceInjector.invoke(provider.$get, provider, undefined, servicename); +}); +</pre></div> + +<p>In the code above we use the <code>config</code> callback in order to define new "provider". Provider is an object, which has a method called <code>$get</code>. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.</p> + +<p>Each service, filter, directive and controller has a provider (i.e. object which factory method, called <code>$get</code>), which is responsible for creating the component's instance.</p> + +<p>We can dig a little bit deeper in AngularJS' implementation:</p> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-c">//...</span> + +<span class="pl-c1">createInternalInjector</span>(instanceCache, <span class="pl-k">function</span>(<span class="pl-smi">servicename</span>) { + <span class="pl-k">var</span> provider <span class="pl-k">=</span> providerInjector.<span class="pl-c1">get</span>(servicename <span class="pl-k">+</span> providerSuffix); + <span class="pl-k">return</span> instanceInjector.<span class="pl-c1">invoke</span>(provider.$get, provider, <span class="pl-c1">undefined</span>, servicename); }, strictDi)); -//<span class="hljs-keyword">...</span> +<span class="pl-c">//...</span> -<span class="hljs-keyword">function</span> invoke(fn, self, locals, serviceName){ - <span class="hljs-keyword">if</span> (typeof locals === <span class="hljs-string">'string'</span>) { - serviceName = locals; - locals = null; +<span class="pl-k">function</span> <span class="pl-en">invoke</span>(<span class="pl-smi">fn</span>, <span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">serviceName</span>){ + <span class="pl-k">if</span> (<span class="pl-k">typeof</span> locals <span class="pl-k">===</span> <span class="pl-s"><span class="pl-pds">'</span>string<span class="pl-pds">'</span></span>) { + serviceName <span class="pl-k">=</span> locals; + locals <span class="pl-k">=</span> <span class="pl-c1">null</span>; } - var args = [], - $inject = annotate(fn, strictDi, serviceName), + <span class="pl-k">var</span> args <span class="pl-k">=</span> [], + $inject <span class="pl-k">=</span> <span class="pl-c1">annotate</span>(fn, strictDi, serviceName), length, i, key; - <span class="hljs-keyword">for</span>(i = <span class="hljs-number">0</span>, length = $inject.length; i < length; i++) { - key = $inject[i]; - <span class="hljs-keyword">if</span> (typeof key !== <span class="hljs-string">'string'</span>) { - throw $injectorMinErr(<span class="hljs-string">'itkn'</span>, - <span class="hljs-string">'Incorrect injection token! Expected service name as string, got {0}'</span>, key); + <span class="pl-k">for</span>(i <span class="pl-k">=</span> <span class="pl-c1">0</span>, length <span class="pl-k">=</span> $inject.<span class="pl-c1">length</span>; i <span class="pl-k"><</span> length; i<span class="pl-k">++</span>) { + key <span class="pl-k">=</span> $inject[i]; + <span class="pl-k">if</span> (<span class="pl-k">typeof</span> key <span class="pl-k">!==</span> <span class="pl-s"><span class="pl-pds">'</span>string<span class="pl-pds">'</span></span>) { + <span class="pl-k">throw</span> $<span class="pl-c1">injectorMinErr</span>(<span class="pl-s"><span class="pl-pds">'</span>itkn<span class="pl-pds">'</span></span>, + <span class="pl-s"><span class="pl-pds">'</span>Incorrect injection token! Expected service name as string, got {0}<span class="pl-pds">'</span></span>, key); } - args.push( - locals && locals.hasOwnProperty(key) - ? locals[key] - : getService(key) + args.<span class="pl-c1">push</span>( + locals <span class="pl-k">&&</span> locals.<span class="pl-c1">hasOwnProperty</span>(key) + <span class="pl-k">?</span> locals[key] + <span class="pl-k">:</span> <span class="pl-c1">getService</span>(key) ); } - <span class="hljs-keyword">if</span> (!fn.$inject) { - // this means that we must be an array. - fn = fn[length]; + <span class="pl-k">if</span> (<span class="pl-k">!</span>fn.$inject) { + <span class="pl-c">// this means that we must be an array.</span> + fn <span class="pl-k">=</span> fn[length]; } - <span class="hljs-keyword">return</span> fn.apply(self, args); -}</code></pre><p>From the example above we can notice how the <code>$get</code> method is actually used:</p> -<pre class="hljs"><code>instanceInjector.<span class="hljs-function"><span class="hljs-title">invoke</span><span class="hljs-params">(provider.<span class="hljs-variable">$get</span>, provider, undefined, servicename)</span></span></code></pre><p>The snippet above calls the <code>invoke</code> method of <code>instanceInjector</code> with the factory method (i.e. <code>$get</code>) of given service, as first argument. Inside <code>invoke</code>'s body <code>annotate</code> is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: <code>fn.apply(self, args)</code>.</p> -<p>If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product".</p> + <span class="pl-k">return</span> fn.<span class="pl-c1">apply</span>(self, args); +}</pre></div> + +<p>From the example above we can notice how the <code>$get</code> method is actually used:</p> + +<div class="highlight highlight-JavaScript"><pre>instanceInjector.<span class="pl-c1">invoke</span>(provider.$get, provider, <span class="pl-c1">undefined</span>, servicename)</pre></div> + +<p>The snippet above calls the <code>invoke</code> method of <code>instanceInjector</code> with the factory method (i.e. <code>$get</code>) of given service, as first argument. Inside <code>invoke</code>'s body <code>annotate</code> is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: <code>fn.apply(self, args)</code>.</p> + +<p>If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product".</p> + <p>There are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:</p> -<ul class="list"> + +<ul> <li>The most appropriate moment, when the component needs to be instantiated</li> <li>Resolving all the dependencies required by the component</li> <li>The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)</li> </ul> -<h4 id="decorator">Decorator</h4> + +<h4> +<a id="decorator" class="anchor" href="#decorator" aria-hidden="true"><span class="octicon octicon-link"></span></a>Decorator</h4> + <blockquote> <p>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.</p> </blockquote> -<p class="img-container"><img src="./decorator.svg" alt="Decorator" title="Fig. 4"></p> -<p>AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method <code>decorator</code> of <code>$provide</code> you can create "wrapper" of any service you have previously defined or used by a third-party:</p> -<pre class="hljs"><code>myModule.controller(<span class="hljs-string">'MainCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(foo)</span> </span>{ - foo.bar(); + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/decorator.svg" alt="Decorator" title="Fig. 4"></p> + +<p>AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method <code>decorator</code> of <code>$provide</code> you can create "wrapper" of any service you have previously defined or used by a third-party:</p> + +<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">foo</span>) { + foo.<span class="pl-c1">bar</span>(); }); -myModule.factory(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-keyword">return</span> { - bar: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - console.log(<span class="hljs-string">'I\'m bar'</span>); +myModule.<span class="pl-c1">factory</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { + <span class="pl-k">return</span> { + <span class="pl-en">bar</span><span class="pl-k">:</span> <span class="pl-k">function</span> () { + <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m bar<span class="pl-pds">'</span></span>); }, - baz: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - console.log(<span class="hljs-string">'I\'m baz'</span>); + <span class="pl-en">baz</span><span class="pl-k">:</span> <span class="pl-k">function</span> () { + <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m baz<span class="pl-pds">'</span></span>); } }; }); -myModule.config(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$provide</span>)</span> </span>{ - <span class="hljs-variable">$provide</span>.decorator(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$delegate</span>)</span> </span>{ - <span class="hljs-keyword">var</span> barBackup = <span class="hljs-variable">$delegate</span>.bar; - <span class="hljs-variable">$delegate</span>.bar = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - console.log(<span class="hljs-string">'Decorated'</span>); - barBackup.apply(<span class="hljs-variable">$delegate</span>, arguments); +myModule.<span class="pl-c1">config</span>(<span class="pl-k">function</span> (<span class="pl-smi">$provide</span>) { + $provide.<span class="pl-c1">decorator</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$delegate</span>) { + <span class="pl-k">var</span> barBackup <span class="pl-k">=</span> $delegate.<span class="pl-c1">bar</span>; + <span class="pl-c1">$delegate</span>.<span class="pl-en">bar</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { + <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>Decorated<span class="pl-pds">'</span></span>); + barBackup.<span class="pl-c1">apply</span>($delegate, arguments); }; - <span class="hljs-keyword">return</span> <span class="hljs-variable">$delegate</span>; + <span class="pl-k">return</span> $delegate; }); -});</code></pre><p>The example above defines new service called <code>foo</code>. In the <code>config</code> callback is called the method <code>$provide.decorator</code> with first argument <code>"foo"</code>, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. <code>$delegate</code> keeps reference to the original service <code>foo</code>. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function. -We decorate the service by overriding its method <code>bar</code>. The actual decoration is simply extending <code>bar</code> by invoking one more <code>console.log statement</code> - <code>console.log('Decorated');</code> and after that call the original <code>bar</code> method with the appropriate context.</p> -<p>Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">aspect-oriented programming</a>. The only AOP framework for AngularJS I'm aware of could be found at <a href="https://github.com/mgechev/angular-aop">github.com/mgechev/angular-aop</a>.</p> -<h4 id="facade">Facade</h4> +});</pre></div> + +<p>The example above defines new service called <code>foo</code>. In the <code>config</code> callback is called the method <code>$provide.decorator</code> with first argument <code>"foo"</code>, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. <code>$delegate</code> keeps reference to the original service <code>foo</code>. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function. +We decorate the service by overriding its method <code>bar</code>. The actual decoration is simply extending <code>bar</code> by invoking one more <code>console.log statement</code> - <code>console.log('Decorated');</code> and after that call the original <code>bar</code> method with the appropriate context.</p> + +<p>Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">aspect-oriented programming</a>. The only AOP framework for AngularJS I'm aware of could be found at <a href="https://github.com/mgechev/angular-aop">github.com/mgechev/angular-aop</a>.</p> + +<h4> +<a id="facade" class="anchor" href="#facade" aria-hidden="true"><span class="octicon octicon-link"></span></a>Facade</h4> + <blockquote> <p>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:</p> -<ol class="list"> -<li><p>make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;</p> -</li> -<li><p>make the library more readable, for the same reason;</p> -</li> -<li><p>reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;</p> -</li> -<li><p>wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).</p> -</li> + +<ol> +<li><p>make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;</p></li> +<li><p>make the library more readable, for the same reason;</p></li> +<li><p>reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;</p></li> +<li><p>wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).</p></li> </ol> </blockquote> -<p class="img-container"><img src="./facade.svg" alt="Facade" title="Fig. 11"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/facade.svg" alt="Facade" title="Fig. 11"></p> + <p>There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.</p> + <p>For example, lets take a look how we can create an <code>XMLHttpRequest</code> POST request:</p> -<pre class="hljs"><code>var <span class="hljs-keyword">http</span> = new XMLHttpRequest(), - url = <span class="hljs-string">'/example/new'</span>, - params = encodeURIComponent(data); -<span class="hljs-keyword">http</span>.<span class="hljs-keyword">open</span>(<span class="hljs-string">"POST"</span>, url, true); - -<span class="hljs-keyword">http</span>.setRequestHeader(<span class="hljs-string">"Content-type"</span>, <span class="hljs-string">"application/x-www-form-urlencoded"</span>); -<span class="hljs-keyword">http</span>.setRequestHeader(<span class="hljs-string">"Content-length"</span>, params.length); -<span class="hljs-keyword">http</span>.setRequestHeader(<span class="hljs-string">"Connection"</span>, <span class="hljs-string">"close"</span>); - -<span class="hljs-keyword">http</span>.onreadystatechange = function () { - <span class="hljs-keyword">if</span>(<span class="hljs-keyword">http</span>.readyState == <span class="hljs-number">4</span> && <span class="hljs-keyword">http</span>.status == <span class="hljs-number">200</span>) { - alert(<span class="hljs-keyword">http</span>.responseText); + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">var</span> http <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">XMLHttpRequest</span>(), + url <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>/example/new<span class="pl-pds">'</span></span>, + params <span class="pl-k">=</span> <span class="pl-c1">encodeURIComponent</span>(data); +http.<span class="pl-c1">open</span>(<span class="pl-s"><span class="pl-pds">"</span>POST<span class="pl-pds">"</span></span>, url, <span class="pl-c1">true</span>); + +http.<span class="pl-c1">setRequestHeader</span>(<span class="pl-s"><span class="pl-pds">"</span>Content-type<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>application/x-www-form-urlencoded<span class="pl-pds">"</span></span>); +http.<span class="pl-c1">setRequestHeader</span>(<span class="pl-s"><span class="pl-pds">"</span>Content-length<span class="pl-pds">"</span></span>, params.<span class="pl-c1">length</span>); +http.<span class="pl-c1">setRequestHeader</span>(<span class="pl-s"><span class="pl-pds">"</span>Connection<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>close<span class="pl-pds">"</span></span>); + +<span class="pl-c1">http</span>.<span class="pl-en">onreadystatechange</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { + <span class="pl-k">if</span>(http.<span class="pl-c1">readyState</span> <span class="pl-k">==</span> <span class="pl-c1">4</span> <span class="pl-k">&&</span> http.<span class="pl-c1">status</span> <span class="pl-k">==</span> <span class="pl-c1">200</span>) { + <span class="pl-c1">alert</span>(http.<span class="pl-c1">responseText</span>); } } -<span class="hljs-keyword">http</span>.send(params);</code></pre><p>But if we want to post this data using the AngularJS' <code>$http</code> service we can:</p> -<pre class="hljs"><code>$http({ - <span class="hljs-keyword">method</span>: '<span class="hljs-type">POST</span>', - url: '/example/new', - data: data +http.<span class="pl-c1">send</span>(params);</pre></div> + +<p>But if we want to post this data using the AngularJS' <code>$http</code> service we can:</p> + +<div class="highlight highlight-JavaScript"><pre>$<span class="pl-c1">http</span>({ + method<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>POST<span class="pl-pds">'</span></span>, + url<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>/example/new<span class="pl-pds">'</span></span>, + data<span class="pl-k">:</span> data }) -.then(function (response) { - alert(response); -});</code></pre><p>or we can even:</p> -<pre class="hljs"><code>$http.post(<span class="hljs-string">'/someUrl'</span>, data) -.<span class="hljs-keyword">then</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(response)</span></span> { - alert(response); -});</code></pre><p>The second option provides pre-configured version, which creates a HTTP POST request to the given URL.</p> +.<span class="pl-c1">then</span>(<span class="pl-k">function</span> (<span class="pl-smi">response</span>) { + <span class="pl-c1">alert</span>(response); +});</pre></div> + +<p>or we can even:</p> + +<div class="highlight highlight-JavaScript"><pre>$http.<span class="pl-c1">post</span>(<span class="pl-s"><span class="pl-pds">'</span>/someUrl<span class="pl-pds">'</span></span>, data) +.<span class="pl-c1">then</span>(<span class="pl-k">function</span> (<span class="pl-smi">response</span>) { + <span class="pl-c1">alert</span>(response); +});</pre></div> + +<p>The second option provides pre-configured version, which creates a HTTP POST request to the given URL.</p> + <p>Even higher level of abstraction is being created by <code>$resource</code>, which is build over the <code>$http</code> service. We will take a further look at this service in <a href="#active-record">Active Record</a> and <a href="#proxy">Proxy</a> sections.</p> -<h4 id="proxy">Proxy</h4> + +<h4> +<a id="proxy" class="anchor" href="#proxy" aria-hidden="true"><span class="octicon octicon-link"></span></a>Proxy</h4> + <blockquote> <p>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.</p> </blockquote> -<p class="img-container"><img src="./proxy.svg" alt="Proxy" title="Fig. 9"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/proxy.svg" alt="Proxy" title="Fig. 9"></p> + <p>We can distinguish three different types of proxy:</p> -<ul class="list"> + +<ul> <li>Virtual Proxy</li> <li>Remote Proxy</li> <li>Protection Proxy</li> </ul> -<p>In this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.</p> + +<p>In this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.</p> + <p>In the snippet bellow, there is a call to the <code>get</code> method of <code>$resource</code> instance, called <code>User</code>:</p> -<pre class="hljs"><code><span class="hljs-built_in">var</span> User <span class="hljs-subst">=</span> <span class="hljs-variable">$resource</span>(<span class="hljs-string">'/users/:id'</span>), - user <span class="hljs-subst">=</span> User<span class="hljs-built_in">.</span>get({ id: <span class="hljs-number">42</span> }); -console<span class="hljs-built_in">.</span><span class="hljs-keyword">log</span>(user); <span class="hljs-comment">//{}</span></code></pre><p><code>console.log</code> would outputs an empty object. Since the AJAX request, which happens behind the scene, when <code>User.get</code> is invoked, is asynchronous, we don't have the actual user when <code>console.log</code> is called. Just after <code>User.get</code> makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.</p> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $<span class="pl-c1">resource</span>(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), + user <span class="pl-k">=</span> User.<span class="pl-c1">get</span>({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); +<span class="pl-en">console</span><span class="pl-c1">.log</span>(user); <span class="pl-c">//{}</span></pre></div> + +<p><code>console.log</code> would outputs an empty object. Since the AJAX request, which happens behind the scene, when <code>User.get</code> is invoked, is asynchronous, we don't have the actual user when <code>console.log</code> is called. Just after <code>User.get</code> makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.</p> + <p>How does this works with AngularJS? Well, lets consider the following snippet:</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MainCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, <span class="hljs-variable">$resource</span>)</span> </span>{ - <span class="hljs-keyword">var</span> User = <span class="hljs-variable">$resource</span>(<span class="hljs-string">'/users/:id'</span>), - <span class="hljs-variable">$scope</span>.user = User.get({ id: <span class="hljs-number">42</span> }); -}</code></pre><pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">span</span> <span class="hljs-attribute">ng-bind</span>=<span class="hljs-value">"user.name"</span>></span><span class="hljs-tag"></<span class="hljs-title">span</span>></span></code></pre><p>Initially when the snippet above executes, the property <code>user</code> of the <code>$scope</code> object will be with value an empty object (<code>{}</code>), which means that <code>user.name</code> will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next <code>$digest</code> loop AngularJS will detect change in <code>$scope.user</code>, which will lead to update of the view.</p> -<h4 id="active-record">Active Record</h4> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">$resource</span>) { + <span class="pl-k">var</span> User <span class="pl-k">=</span> $<span class="pl-c1">resource</span>(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), + $scope.<span class="pl-c1">user</span> <span class="pl-k">=</span> User.<span class="pl-c1">get</span>({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); +}</pre></div> + +<div class="highlight highlight-html"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>user.name<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> + +<p>Initially when the snippet above executes, the property <code>user</code> of the <code>$scope</code> object will be with value an empty object (<code>{}</code>), which means that <code>user.name</code> will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next <code>$digest</code> loop AngularJS will detect change in <code>$scope.user</code>, which will lead to update of the view.</p> + +<h4> +<a id="active-record" class="anchor" href="#active-record" aria-hidden="true"><span class="octicon octicon-link"></span></a>Active Record</h4> + <blockquote> <p>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.</p> </blockquote> -<p class="img-container"><img src="./active-record.svg" alt="Active Record" title="Fig. 7"></p> -<p>AngularJS defines a service called <code>$resource</code>. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.</p> -<p>According to the AngularJS' documentation <code>$resource</code> is:</p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/active-record.svg" alt="Active Record" title="Fig. 7"></p> + +<p>AngularJS defines a service called <code>$resource</code>. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.</p> + +<p>According to the AngularJS' documentation <code>$resource</code> is:</p> + <blockquote> <p>A factory which creates a resource object that lets you interact with RESTful server-side data sources. The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.</p> </blockquote> + <p>Here is how <code>$resource</code> could be used:</p> -<pre class="hljs"><code><span class="hljs-built_in">var</span> User <span class="hljs-subst">=</span> <span class="hljs-variable">$resource</span>(<span class="hljs-string">'/users/:id'</span>), - user <span class="hljs-subst">=</span> <span class="hljs-literal">new</span> User({ - name: <span class="hljs-string">'foo'</span>, - age : <span class="hljs-number">42</span> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $<span class="pl-c1">resource</span>(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), + user <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">User</span>({ + name<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, + age <span class="pl-k">:</span> <span class="pl-c1">42</span> }); -user<span class="hljs-built_in">.</span><span class="hljs-variable">$save</span>();</code></pre><p>The call of <code>$resource</code> will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.</p> +user.$<span class="pl-c1">save</span>();</pre></div> + +<p>The call of <code>$resource</code> will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.</p> + <p>This way we can use the constructor function and its static methods by:</p> -<pre class="hljs"><code><span class="hljs-tag">User</span><span class="hljs-class">.get</span>({ <span class="hljs-attribute">userid</span>: userid });</code></pre><p>The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see <a href="#proxy">proxy</a>).</p> -<p>You can find more details for <code>$resource</code> <a href="http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/">The magic of $resource</a> and <a href="https://docs.angularjs.org/api/ngResource/service/$resource">AngularJS' documentation</a>.</p> + +<div class="highlight highlight-JavaScript"><pre>User.<span class="pl-c1">get</span>({ userid<span class="pl-k">:</span> userid });</pre></div> + +<p>The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see <a href="#proxy">proxy</a>).</p> + +<p>You can find more details for <code>$resource</code> <a href="http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/">The magic of $resource</a> and <a href="https://docs.angularjs.org/api/ngResource/service/%24resource">AngularJS' documentation</a>.</p> + <p>Since Martin Fowler states that</p> + <blockquote> <p>responsibility of the Active Record object is to take care of the communication with the databse in order to create...</p> </blockquote> -<p><code>$resource</code> does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as "Active Record like RESTful communication".</p> -<h4 id="intercepting-filters">Intercepting Filters</h4> + +<p><code>$resource</code> does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as "Active Record like RESTful communication".</p> + +<h4> +<a id="intercepting-filters" class="anchor" href="#intercepting-filters" aria-hidden="true"><span class="octicon octicon-link"></span></a>Intercepting Filters</h4> + <blockquote> <p>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.</p> </blockquote> -<p class="img-container"><img src="./intercepting-filters.svg" alt="Composite" title="Fig. 3"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/intercepting-filters.svg" alt="Composite" title="Fig. 3"></p> + <p>In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.</p> + <p>In AngularJS we have the idea of the Intercepting Filters in <code>$httpProvider</code>. <code>$httpProvider</code> has an array property called <code>interceptors</code>, which contains a list of objects. Each object may have properties called: <code>request</code>, <code>response</code>, <code>requestError</code>, <code>responseError</code>.</p> + <p><code>requestError</code> is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively <code>responseError</code> is being called when the previous <code>response</code> interceptor has thrown an error.</p> + <p>Here is a basic example how you can add interceptors using object literal:</p> -<pre class="hljs"><code><span class="hljs-variable">$httpProvider</span>.interceptors.push(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(<span class="hljs-variable">$q</span>, dependency1, dependency2)</span> </span>{ - <span class="hljs-keyword">return</span> { - <span class="hljs-string">'request'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(config)</span> </span>{ - <span class="hljs-comment">// same as above</span> + +<div class="highlight highlight-JavaScript"><pre>$httpProvider.<span class="pl-c1">interceptors</span>.<span class="pl-c1">push</span>(<span class="pl-k">function</span>(<span class="pl-smi">$q</span>, <span class="pl-smi">dependency1</span>, <span class="pl-smi">dependency2</span>) { + <span class="pl-k">return</span> { + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">request</span><span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">config</span>) { + <span class="pl-c">// same as above</span> }, - <span class="hljs-string">'response'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(response)</span> </span>{ - <span class="hljs-comment">// same as above</span> + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">response</span><span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">response</span>) { + <span class="pl-c">// same as above</span> } }; -});</code></pre><h3 id="directives">Directives</h3> -<h4 id="composite">Composite</h4> +});</pre></div> + +<h3> +<a id="directives-1" class="anchor" href="#directives-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Directives</h3> + +<h4> +<a id="composite" class="anchor" href="#composite" aria-hidden="true"><span class="octicon octicon-link"></span></a>Composite</h4> + <blockquote> -<p>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies.</p> +<p>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies.</p> </blockquote> -<p class="img-container"><img src="./composite.svg" alt="Composite" title="Fig. 3"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/composite.svg" alt="Composite" title="Fig. 3"></p> + <p>According to the Gang of Four, MVC is nothing more than combination of:</p> -<ul class="list"> + +<ul> <li>Strategy</li> <li>Composite</li> <li>Observer</li> </ul> + <p>They state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.</p> + <p>Lets look at the following example:</p> -<pre class="hljs"><code><span class="hljs-doctype"><!doctype html></span> -<span class="hljs-tag"><<span class="hljs-title">html</span>></span> - <span class="hljs-tag"><<span class="hljs-title">head</span>></span> - <span class="hljs-tag"></<span class="hljs-title">head</span>></span> - <span class="hljs-tag"><<span class="hljs-title">body</span>></span> - <span class="hljs-tag"><<span class="hljs-title">zippy</span> <span class="hljs-attribute">title</span>=<span class="hljs-value">"Zippy"</span>></span> + +<div class="highlight highlight-HTML"><pre><!doctype html> +<<span class="pl-ent">html</span>> + <<span class="pl-ent">head</span>> + </<span class="pl-ent">head</span>> + <<span class="pl-ent">body</span>> + <<span class="pl-ent">zippy</span> <span class="pl-e">title</span>=<span class="pl-s"><span class="pl-pds">"</span>Zippy<span class="pl-pds">"</span></span>> Zippy! - <span class="hljs-tag"></<span class="hljs-title">zippy</span>></span> - <span class="hljs-tag"></<span class="hljs-title">body</span>></span> -<span class="hljs-tag"></<span class="hljs-title">html</span>></span></code></pre><pre class="hljs"><code>myModule.directive('zippy', function () { - <span class="hljs-keyword">return</span> { - restrict: 'E', - <span class="hljs-keyword">template</span>: '<<span class="hljs-keyword">div</span>><<span class="hljs-keyword">div</span> class=<span class="hljs-string">"header"</span>></<span class="hljs-keyword">div</span>><<span class="hljs-keyword">div</span> class=<span class="hljs-string">"content"</span> ng-transclude></<span class="hljs-keyword">div</span>></<span class="hljs-keyword">div</span>>', - link: function (scope, el) { - el.find('.header').click(function () { - el.find('.content').toggle(); + </<span class="pl-ent">zippy</span>> + </<span class="pl-ent">body</span>> +</<span class="pl-ent">html</span>></pre></div> + +<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">directive</span>(<span class="pl-s"><span class="pl-pds">'</span>zippy<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { + <span class="pl-k">return</span> { + restrict<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>E<span class="pl-pds">'</span></span>, + template<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span><div><div class="header"></div><div class="content" ng-transclude></div></div><span class="pl-pds">'</span></span>, + <span class="pl-en">link</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span class="pl-smi">scope</span>, <span class="pl-smi">el</span>) { + el.<span class="pl-c1">find</span>(<span class="pl-s"><span class="pl-pds">'</span>.header<span class="pl-pds">'</span></span>).<span class="pl-c1">click</span>(<span class="pl-k">function</span> () { + el.<span class="pl-c1">find</span>(<span class="pl-s"><span class="pl-pds">'</span>.content<span class="pl-pds">'</span></span>).<span class="pl-c1">toggle</span>(); }); } } -});</code></pre><p>This example defines a simple directive, which is a UI component. The defined component (called "zippy") has header and content. Click on its header toggles the visibility of the content.</p> +});</pre></div> + +<p>This example defines a simple directive, which is a UI component. The defined component (called "zippy") has header and content. Click on its header toggles the visibility of the content.</p> + <p>From the first example we can note that the whole DOM tree is a composition of elements. The root component is the <code>html</code> element, directly followed by the nested elements <code>head</code> and <code>body</code> and so on...</p> + <p>In the second, JavaScript, example we see that the <code>template</code> property of the directive, contains markup with <code>ng-transclude</code> directive inside it. So this means that inside the directive <code>zippy</code> we have another directive called <code>ng-transclude</code>, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.</p> -<h3 id="interpreter">Interpreter</h3> + +<h3> +<a id="interpreter" class="anchor" href="#interpreter" aria-hidden="true"><span class="octicon octicon-link"></span></a>Interpreter</h3> + <blockquote> <p>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.</p> </blockquote> -<p class="img-container"><img src="./interpreter.svg" alt="Interpreter" title="Fig. 6"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/interpreter.svg" alt="Interpreter" title="Fig. 6"></p> + <p>Behind its <code>$parse</code> service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:</p> -<ul class="list"> + +<ul> <li>may contain filters with UNIX like pipe syntax</li> -<li>don't throw any errors</li> -<li>don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)</li> +<li>don't throw any errors</li> +<li>don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)</li> <li>are evaluated in given context (the context of the current <code>$scope</code>)</li> </ul> + <p>Inside the <code>$parse</code> service are defined two main components:</p> -<pre class="hljs"><code><span class="hljs-comment">//Responsible for converting given string into tokens</span> -<span class="hljs-keyword">var</span> Lexer; -<span class="hljs-comment">//Responsible for parsing the tokens and evaluating the expression</span> -<span class="hljs-keyword">var</span> Parser;</code></pre><p>Once given expression have been tokenized it is cached internally, because of performance concerns.</p> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-c">//Responsible for converting given string into tokens</span> +<span class="pl-k">var</span> Lexer; +<span class="pl-c">//Responsible for parsing the tokens and evaluating the expression</span> +<span class="pl-k">var</span> Parser;</pre></div> + +<p>Once given expression have been tokenized it is cached internally, because of performance concerns.</p> + <p>The terminal expressions in the AngularJS DSL are defined as follows:</p> -<pre class="hljs"><code><span class="hljs-keyword">var</span> OPERATORS = { - <span class="hljs-comment">/* jshint bitwise : false */</span> - <span class="hljs-string">'null'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;}, - <span class="hljs-string">'true'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;}, - <span class="hljs-string">'false'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;}, - undefined:noop, - <span class="hljs-string">'+'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{ - <span class="hljs-comment">//...</span> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">var</span> <span class="pl-c1">OPERATORS</span> <span class="pl-k">=</span> { + <span class="pl-c">/* jshint bitwise : false */</span> + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">null</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(){<span class="pl-k">return</span> <span class="pl-c1">null</span>;}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">true</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(){<span class="pl-k">return</span> <span class="pl-c1">true</span>;}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">false</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(){<span class="pl-k">return</span> <span class="pl-c1">false</span>;}, + <span class="pl-c1">undefined</span><span class="pl-k">:</span>noop, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">+</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){ + <span class="pl-c">//...</span> }, - <span class="hljs-string">'*'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)*b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'/'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)/b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'%'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)%b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'^'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)^b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'='</span>:noop, - <span class="hljs-string">'==='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a, b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)===b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'!=='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a, b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)!==b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'=='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)==b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'!='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)!=b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'<'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)<b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'>'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)>b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'<='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)<=b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'>='</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)>=b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'&&'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)&&b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'||'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)||b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'&'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> a(<span class="hljs-keyword">self</span>, locals)&b(<span class="hljs-keyword">self</span>, locals);}, - <span class="hljs-string">'|'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a,b)</span></span>{<span class="hljs-keyword">return</span> b(<span class="hljs-keyword">self</span>, locals)(<span class="hljs-keyword">self</span>, locals, a(<span class="hljs-keyword">self</span>, locals));}, - <span class="hljs-string">'!'</span>:<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(self, locals, a)</span></span>{<span class="hljs-keyword">return</span> !a(<span class="hljs-keyword">self</span>, locals);} -};</code></pre><p>We can think of the function associated with each terminal as implementation of the <code>AbstractExpression</code>'s interface.</p> + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">*</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">*</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">/</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)/<span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">%</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">%</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">^</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">^</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span>=<span class="pl-pds">'</span></span><span class="pl-k">:</span>noop, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">===</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>, <span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">===</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!==</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>, <span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">!==</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">==</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">==</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">!=</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en"><</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k"><</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">></span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">></span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en"><=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k"><=</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">>=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">>=</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">&&</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">&&</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">||</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">||</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">&</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">&</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">|</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">b</span>(self, locals)(self, locals, <span class="pl-c1">a</span>(self, locals));}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>){<span class="pl-k">return</span> <span class="pl-k">!</span><span class="pl-c1">a</span>(self, locals);} +};</pre></div> + +<p>We can think of the function associated with each terminal as implementation of the <code>AbstractExpression</code>'s interface.</p> + <p>Each <code>Client</code> interprets given AngularJS expression in a specific context - specific scope.</p> + <p>Few sample AngularJS expressions are:</p> -<pre class="hljs"><code>// toUpperCase filter <span class="hljs-keyword">is</span> applied to the <span class="hljs-literal">result</span> <span class="hljs-keyword">of</span> the expression -// (foo) ? bar : baz -(foo) ? bar : baz | toUpperCase</code></pre><h4 id="template-view">Template View</h4> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-c">// toUpperCase filter is applied to the result of the expression</span> +<span class="pl-c">// (foo) ? bar : baz</span> +(foo) <span class="pl-k">?</span> bar <span class="pl-k">:</span> baz | toUpperCase</pre></div> + +<h4> +<a id="template-view" class="anchor" href="#template-view" aria-hidden="true"><span class="octicon octicon-link"></span></a>Template View</h4> + <blockquote> <p>Renders information into HTML by embedding markers in an HTML page.</p> </blockquote> -<p class="img-container"><img src="./template-view.svg" alt="Template View" title="Fig. 8"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/template-view.svg" alt="Template View" title="Fig. 8"></p> + <p>The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.</p> + <p>Templates are very commonly used especially in the back-end. For example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.</p> + <p>For JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as <code>script</code> embedded inside your view or even inlined into your JavaScript.</p> + <p>For example:</p> -<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"template/mustache"</span>></span><span class="javascript"> - <h2>Names<<span class="hljs-regexp">/h2> - </span></span></span><span class="hljs-expression">{{<span class="hljs-begin-block">#names</span>}}</span><span class="xml"><span class="javascript"> - <strong></span></span><span class="hljs-expression">{{<span class="hljs-variable">name</span>}}</span><span class="xml"><span class="javascript"><<span class="hljs-regexp">/strong> - </span></span></span><span class="hljs-expression">{{<span class="hljs-end-block">/names</span>}}</span><span class="xml"><span class="javascript"> -</span><span class="hljs-tag"></<span class="hljs-title">script</span>></span></span></code></pre><p>The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.</p> -<p>For example if we evaluate the template above in the context of the following object: <code>{ names: ['foo', 'bar', 'baz'] }</code>, so we will get:</p> -<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">h2</span>></span>Names<span class="hljs-tag"></<span class="hljs-title">h2</span>></span> - <span class="hljs-tag"><<span class="hljs-title">strong</span>></span>foo<span class="hljs-tag"></<span class="hljs-title">strong</span>></span> - <span class="hljs-tag"><<span class="hljs-title">strong</span>></span>bar<span class="hljs-tag"></<span class="hljs-title">strong</span>></span> - <span class="hljs-tag"><<span class="hljs-title">strong</span>></span>baz<span class="hljs-tag"></<span class="hljs-title">strong</span>></span></code></pre><p>AngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are. + +<div class="highlight highlight-html"><pre><span class="pl-s1"><<span class="pl-ent">script</span> <span class="pl-e">type</span>=<span class="pl-s"><span class="pl-pds">"</span>template/mustache<span class="pl-pds">"</span></span>></span> +<span class="pl-s1"> <span class="pl-k"><</span>h2<span class="pl-k">></span>Names<span class="pl-k"><</span>/h2<span class="pl-k">></span></span> +<span class="pl-s1"> {{#names}}</span> +<span class="pl-s1"> <span class="pl-k"><</span>strong<span class="pl-k">></span>{{name}}<span class="pl-k"><</span>/strong<span class="pl-k">></span></span> +<span class="pl-s1"> {{/names}}</span> +<span class="pl-s1"></<span class="pl-ent">script</span>></span></pre></div> + +<p>The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.</p> + +<p>For example if we evaluate the template above in the context of the following object: <code>{ names: ['foo', 'bar', 'baz'] }</code>, so we will get:</p> + +<div class="highlight highlight-html"><pre><<span class="pl-ent">h2</span>>Names</<span class="pl-ent">h2</span>> + <<span class="pl-ent">strong</span>>foo</<span class="pl-ent">strong</span>> + <<span class="pl-ent">strong</span>>bar</<span class="pl-ent">strong</span>> + <<span class="pl-ent">strong</span>>baz</<span class="pl-ent">strong</span>></pre></div> + +<p>AngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are. What AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.</p> + <p>For example:</p> -<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">ul</span> <span class="hljs-attribute">ng-repeat</span>=<span class="hljs-value">"name in names"</span>></span> - <span class="hljs-tag"><<span class="hljs-title">li</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">name</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">li</span>></span> -<span class="hljs-tag"></<span class="hljs-title">ul</span>></span></span></code></pre><p>in the context of the scope:</p> -<pre class="hljs"><code><span class="hljs-variable">$scope</span>.names = [<span class="hljs-string">'foo'</span>, <span class="hljs-string">'bar'</span>, <span class="hljs-string">'baz'</span>];</code></pre><p>will produce the same result as the one above. The main difference here is that the template is not wrapped inside a <code>script</code> tag but is HTML instead.</p> -<h3 id="scope">Scope</h3> -<h4 id="observer">Observer</h4> + +<div class="highlight highlight-html"><pre><<span class="pl-ent">ul</span> <span class="pl-e">ng-repeat</span>=<span class="pl-s"><span class="pl-pds">"</span>name in names<span class="pl-pds">"</span></span>> + <<span class="pl-ent">li</span>>{{name}}</<span class="pl-ent">li</span>> +</<span class="pl-ent">ul</span>></pre></div> + +<p>in the context of the scope:</p> + +<div class="highlight highlight-javascript"><pre>$scope.<span class="pl-c1">names</span> <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>baz<span class="pl-pds">'</span></span>];</pre></div> + +<p>will produce the same result as the one above. The main difference here is that the template is not wrapped inside a <code>script</code> tag but is HTML instead.</p> + +<h3> +<a id="scope-1" class="anchor" href="#scope-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Scope</h3> + +<h4> +<a id="observer" class="anchor" href="#observer" aria-hidden="true"><span class="octicon octicon-link"></span></a>Observer</h4> + <blockquote> <p>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.</p> </blockquote> -<p class="img-container"><img src="./observer.svg" alt="Observer" title="Fig. 7"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg" alt="Observer" title="Fig. 7"></p> + <p>There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see <a href="#scope">Scope</a>). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.</p> + <p>Each AngularJS scope has public methods called <code>$on</code>, <code>$emit</code> and <code>$broadcast</code>. The method <code>$on</code> accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the <code>Observer</code> interface (in JavaScript the functions are first-class, so we can provide only implementation of the <code>notify</code> method):</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExampleCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'event-name'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span><span class="hljs-params">()</span> </span>{ - <span class="hljs-comment">//body</span> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">ExampleCtrl</span>(<span class="pl-smi">$scope</span>) { + $scope.$<span class="pl-c1">on</span>(<span class="pl-s"><span class="pl-pds">'</span>event-name<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> <span class="pl-en">handler</span>() { + <span class="pl-c">//body</span> }); -}</code></pre><p>In this way the current scope "subscribes" to events of type <code>event-name</code>. When <code>event-name</code> is triggered in any parent or child scope of the given one, <code>handler</code> would be called.</p> +}</pre></div> + +<p>In this way the current scope "subscribes" to events of type <code>event-name</code>. When <code>event-name</code> is triggered in any parent or child scope of the given one, <code>handler</code> would be called.</p> + <p>The methods <code>$emit</code> and <code>$broadcast</code> are used for triggering events respectively upwards and downwards through the scope chain. For example:</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExampleCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$emit</span>(<span class="hljs-string">'event-name'</span>, { foo: <span class="hljs-string">'bar'</span> }); -}</code></pre><p>The scope in the example above, triggers the event <code>event-name</code> to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event <code>event-name</code>, would be notified and their handler callback will be invoked.</p> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">ExampleCtrl</span>(<span class="pl-smi">$scope</span>) { + $scope.$<span class="pl-c1">emit</span>(<span class="pl-s"><span class="pl-pds">'</span>event-name<span class="pl-pds">'</span></span>, { foo<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span> }); +}</pre></div> + +<p>The scope in the example above, triggers the event <code>event-name</code> to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event <code>event-name</code>, would be notified and their handler callback will be invoked.</p> + <p>Analogical is the case when the method <code>$broadcast</code> is called. The only difference is that the event would be transmitted downwards - to all children scopes. Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).</p> + <p>In the JavaScript community this pattern is better known as publish/subscribe.</p> + <p>For a best practice example see <a href="#observer-pattern-as-an-external-service">Observer Pattern as an External Service</a></p> -<h4 id="chain-of-responsibilities">Chain of Responsibilities</h4> + +<h4> +<a id="chain-of-responsibilities" class="anchor" href="#chain-of-responsibilities" aria-hidden="true"><span class="octicon octicon-link"></span></a>Chain of Responsibilities</h4> + <blockquote> <p>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.</p> </blockquote> -<p class="img-container"><img src="./chain-of-responsibilities.svg" alt="Chain of Responsibilities" title="Fig. 5"></p> -<p>As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their <code>$parent</code> property.</p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/chain-of-responsibilities.svg" alt="Chain of Responsibilities" title="Fig. 5"></p> + +<p>As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their <code>$parent</code> property.</p> + <p>When <code>$emit</code> or <code>$broadcast</code> are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:</p> -<ul class="list"> + +<ul> <li>Handle the event and pass it to the next scope in the chain</li> <li>Handle the event and stop its propagation</li> <li>Pass the event to the next scope in the chain without handling it</li> <li>Stop the event propagation without handling it</li> </ul> -<p>In the example bellow you can see an example in which <code>ChildCtrl</code> triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in <code>ParentCtrl</code> and the one used in <code>MainCtrl</code>) are going to handle the event by logging into the console: <code>"foo received"</code>. If any of the scopes should be considered as final destination it can call the method <code>stopPropagation</code> of the event object, passed to the callback.</p> -<pre class="hljs"><code>myModule.controller(<span class="hljs-string">'MainCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - console.log(<span class="hljs-string">'foo received'</span>); + +<p>In the example bellow you can see an example in which <code>ChildCtrl</code> triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in <code>ParentCtrl</code> and the one used in <code>MainCtrl</code>) are going to handle the event by logging into the console: <code>"foo received"</code>. If any of the scopes should be considered as final destination it can call the method <code>stopPropagation</code> of the event object, passed to the callback.</p> + +<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { + $scope.$<span class="pl-c1">on</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { + <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); }); }); -myModule.controller(<span class="hljs-string">'ParentCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{ - console.log(<span class="hljs-string">'foo received'</span>); +myModule.<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>ParentCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { + $scope.$<span class="pl-c1">on</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">e</span>) { + <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); }); }); -myModule.controller(<span class="hljs-string">'ChildCtrl'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$emit</span>(<span class="hljs-string">'foo'</span>); -});</code></pre><p>The different handlers from the UML diagram above are the different scopes, injected to the controllers.</p> -<h4 id="command">Command</h4> +myModule.<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>ChildCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { + $scope.$<span class="pl-c1">emit</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>); +});</pre></div> + +<p>The different handlers from the UML diagram above are the different scopes, injected to the controllers.</p> + +<h4> +<a id="command" class="anchor" href="#command" aria-hidden="true"><span class="octicon octicon-link"></span></a>Command</h4> + <blockquote> <p>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.</p> </blockquote> -<p class="img-container"><img src="./command.svg" alt="Command" title="Fig. 11"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/command.svg" alt="Command" title="Fig. 11"></p> + <p>Before continuing with the application of the command pattern lets describe how AngularJS implements data binding.</p> + <p>When we want to bind our model to the view we use the directives <code>ng-bind</code> (for single-way data binding) and <code>ng-model</code> (for two-way data binding). For example, if we want each change in the model <code>foo</code> to reflect the view we can:</p> -<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">span</span> <span class="hljs-attribute">ng-bind</span>=<span class="hljs-value">"foo"</span>></span><span class="hljs-tag"></<span class="hljs-title">span</span>></span></code></pre><p>Now each time we change the value of <code>foo</code> the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:</p> -<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-title">span</span> <span class="hljs-attribute">ng-bind</span>=<span class="hljs-value">"foo + ' ' + bar | uppercase"</span>></span><span class="hljs-tag"></<span class="hljs-title">span</span>></span></code></pre><p>In the example above the value of the span will be the concatenated uppercased value of <code>foo</code> and <code>bar</code>. What happens behind the scene?</p> -<p>Each <code>$scope</code> has method called <code>$watch</code>. When the AngularJS compiler find the directive <code>ng-bind</code> it creates a new watcher of the expression <code>foo + ' ' + bar | uppercase</code>, i.e. <code>$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });</code>. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.</p> + +<div class="highlight highlight-html"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>foo<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> + +<p>Now each time we change the value of <code>foo</code> the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:</p> + +<div class="highlight highlight-html"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>foo + ' ' + bar | uppercase<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> + +<p>In the example above the value of the span will be the concatenated uppercased value of <code>foo</code> and <code>bar</code>. What happens behind the scene?</p> + +<p>Each <code>$scope</code> has method called <code>$watch</code>. When the AngularJS compiler find the directive <code>ng-bind</code> it creates a new watcher of the expression <code>foo + ' ' + bar | uppercase</code>, i.e. <code>$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });</code>. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.</p> + <p>Here are the first a couple of lines of the implementation of <code>$watch</code>:</p> -<pre class="hljs"><code>$watch: <span class="hljs-keyword">function</span>(watchExp, listener, objectEquality) { - var scope = this, - get = compileToFn(watchExp, <span class="hljs-string">'watch'</span>), - array = scope.$$watchers, - watcher = { - fn: listener, - last: initWatchVal, - get: get, - exp: watchExp, - eq: !!objectEquality + +<div class="highlight highlight-javascript"><pre>$<span class="pl-en">watch</span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">watchExp</span>, <span class="pl-smi">listener</span>, <span class="pl-smi">objectEquality</span>) { + <span class="pl-k">var</span> scope <span class="pl-k">=</span> <span class="pl-v">this</span>, + get <span class="pl-k">=</span> <span class="pl-c1">compileToFn</span>(watchExp, <span class="pl-s"><span class="pl-pds">'</span>watch<span class="pl-pds">'</span></span>), + array <span class="pl-k">=</span> scope.$$watchers, + watcher <span class="pl-k">=</span> { + fn<span class="pl-k">:</span> listener, + last<span class="pl-k">:</span> initWatchVal, + get<span class="pl-k">:</span> get, + exp<span class="pl-k">:</span> watchExp, + eq<span class="pl-k">:</span> <span class="pl-k">!!</span>objectEquality }; -//<span class="hljs-keyword">...</span></code></pre><p>We can think of the <code>watcher</code> object as a command. The expression of the command is being evaluated on each <a href="https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest"><code>"$digest"</code></a> loop. Once AngularJS detects change in the expression, it invokes the <code>listener</code> function. The <code>watcher</code> command encapsulates the whole information required for watching given expression and delegates the execution of the command to the <code>listener</code> (the actual receiver). We can think of the <code>$scope</code> as the command's <code>Client</code> and the <code>$digest</code> loop as the command's <code>Invoker</code>.</p> -<h3 id="controllers">Controllers</h3> -<h4 id="page-controller">Page Controller</h4> +<span class="pl-c">//...</span></pre></div> + +<p>We can think of the <code>watcher</code> object as a command. The expression of the command is being evaluated on each <a href="https://docs.angularjs.org/api/ng/type/%24rootScope.Scope#%24digest"><code>"$digest"</code></a> loop. Once AngularJS detects change in the expression, it invokes the <code>listener</code> function. The <code>watcher</code> command encapsulates the whole information required for watching given expression and delegates the execution of the command to the <code>listener</code> (the actual receiver). We can think of the <code>$scope</code> as the command's <code>Client</code> and the <code>$digest</code> loop as the command's <code>Invoker</code>.</p> + +<h3> +<a id="controllers-1" class="anchor" href="#controllers-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Controllers</h3> + +<h4> +<a id="page-controller" class="anchor" href="#page-controller" aria-hidden="true"><span class="octicon octicon-link"></span></a>Page Controller</h4> + <blockquote> <p>An object that handles a request for a specific page or action on a Web site. Martin Fowler</p> </blockquote> -<p class="img-container"><img src="./page-controller.svg" alt="Page Controller" title="Fig. 8"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/page-controller.svg" alt="Page Controller" title="Fig. 8"></p> + <p>According to <a href="#references">4</a> the page controller:</p> + <blockquote> <p>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code</p> </blockquote> -<p>Since there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the <code>$route</code> or <code>$state</code> services and the page rendering is responsibility of the directives <code>ng-view</code>/<code>ui-view</code>.</p> + +<p>Since there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the <code>$route</code> or <code>$state</code> services and the page rendering is responsibility of the directives <code>ng-view</code>/<code>ui-view</code>.</p> + <p>Similarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.</p> + <p>The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap. Here is an example hierarchy between few controllers:</p> -<pre class="hljs"><code><span class="xml"><span class="hljs-doctype"><!doctype html></span> -<span class="hljs-tag"><<span class="hljs-title">html</span>></span> - <span class="hljs-tag"><<span class="hljs-title">head</span>></span> - <span class="hljs-tag"></<span class="hljs-title">head</span>></span> - <span class="hljs-tag"><<span class="hljs-title">body</span> <span class="hljs-attribute">ng-controller</span>=<span class="hljs-value">"MainCtrl"</span>></span> - <span class="hljs-tag"><<span class="hljs-title">div</span> <span class="hljs-attribute">ng-controller</span>=<span class="hljs-value">"ChildCtrl"</span>></span> - <span class="hljs-tag"><<span class="hljs-title">span</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">user.name</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">span</span>></span> - <span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">ng-click</span>=<span class="hljs-value">"click()"</span>></span>Click<span class="hljs-tag"></<span class="hljs-title">button</span>></span> - <span class="hljs-tag"></<span class="hljs-title">div</span>></span> - <span class="hljs-tag"></<span class="hljs-title">body</span>></span> -<span class="hljs-tag"></<span class="hljs-title">html</span>></span></span></code></pre><pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MainCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, <span class="hljs-variable">$location</span>, User)</span> </span>{ - <span class="hljs-keyword">if</span> (!User.isAuthenticated()) { - <span class="hljs-variable">$location</span>.path(<span class="hljs-string">'/unauthenticated'</span>); + +<div class="highlight highlight-HTML"><pre><!doctype html> +<<span class="pl-ent">html</span>> + <<span class="pl-ent">head</span>> + </<span class="pl-ent">head</span>> + <<span class="pl-ent">body</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>MainCtrl<span class="pl-pds">"</span></span>> + <<span class="pl-ent">div</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>ChildCtrl<span class="pl-pds">"</span></span>> + <<span class="pl-ent">span</span>>{{user.name}}</<span class="pl-ent">span</span>> + <<span class="pl-ent">button</span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>click()<span class="pl-pds">"</span></span>>Click</<span class="pl-ent">button</span>> + </<span class="pl-ent">div</span>> + </<span class="pl-ent">body</span>> +</<span class="pl-ent">html</span>></pre></div> + +<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">$location</span>, <span class="pl-smi">User</span>) { + <span class="pl-k">if</span> (<span class="pl-k">!</span>User.<span class="pl-c1">isAuthenticated</span>()) { + $location.<span class="pl-c1">path</span>(<span class="pl-s"><span class="pl-pds">'</span>/unauthenticated<span class="pl-pds">'</span></span>); } } -<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ChildCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, User)</span> </span>{ - <span class="hljs-variable">$scope</span>.click = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - alert(<span class="hljs-string">'You clicked me!'</span>); +<span class="pl-k">function</span> <span class="pl-en">ChildCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">User</span>) { + <span class="pl-c1">$scope</span>.<span class="pl-en">click</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { + <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>You clicked me!<span class="pl-pds">'</span></span>); }; - <span class="hljs-variable">$scope</span>.user = User.get(<span class="hljs-number">0</span>); -}</code></pre><p>This example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.</p> -<p>The <code>ChildCtrl</code> is responsible for handling actions such as clicking the button with label <code>"Click"</code> and exposing the model to the view, by attaching it to the scope.</p> -<h3 id="others">Others</h3> -<h4 id="module-pattern">Module Pattern</h4> + $scope.<span class="pl-c1">user</span> <span class="pl-k">=</span> User.<span class="pl-c1">get</span>(<span class="pl-c1">0</span>); +}</pre></div> + +<p>This example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.</p> + +<p>The <code>ChildCtrl</code> is responsible for handling actions such as clicking the button with label <code>"Click"</code> and exposing the model to the view, by attaching it to the scope.</p> + +<h3> +<a id="others" class="anchor" href="#others" aria-hidden="true"><span class="octicon octicon-link"></span></a>Others</h3> + +<h4> +<a id="module-pattern" class="anchor" href="#module-pattern" aria-hidden="true"><span class="octicon octicon-link"></span></a>Module Pattern</h4> + <p>This is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.</p> -<p>Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:</p> -<pre class="hljs"><code><span class="hljs-keyword">var</span> Page = (<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-keyword">var</span> title; +<p>Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:</p> + +<div class="highlight highlight-javascript"><pre><span class="pl-k">var</span> Page <span class="pl-k">=</span> (<span class="pl-k">function</span> () { - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setTitle</span><span class="hljs-params">(t)</span> </span>{ - <span class="hljs-built_in">document</span>.title = t; - title = t; + <span class="pl-k">var</span> title; + + <span class="pl-k">function</span> <span class="pl-en">setTitle</span>(<span class="pl-smi">t</span>) { + <span class="pl-c1">document</span>.<span class="pl-c1">title</span> <span class="pl-k">=</span> t; + title <span class="pl-k">=</span> t; } - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTitle</span><span class="hljs-params">()</span> </span>{ - <span class="hljs-keyword">return</span> title; + <span class="pl-k">function</span> <span class="pl-en">getTitle</span>() { + <span class="pl-k">return</span> title; } - <span class="hljs-keyword">return</span> { - setTitle: setTitle, - getTitle: getTitle + <span class="pl-k">return</span> { + setTitle<span class="pl-k">:</span> setTitle, + getTitle<span class="pl-k">:</span> getTitle }; -}());</code></pre><p>In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (<code>setTitle</code> and <code>getTitle</code>). The returned object is being assigned to the <code>Page</code> variable.</p> -<p>In this case the user of the <code>Page</code> object doesn't has direct access to the <code>title</code> variable, which is defined inside the local scope of the IIFE.</p> +}());</pre></div> + +<p>In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (<code>setTitle</code> and <code>getTitle</code>). The returned object is being assigned to the <code>Page</code> variable.</p> + +<p>In this case the user of the <code>Page</code> object doesn't has direct access to the <code>title</code> variable, which is defined inside the local scope of the IIFE.</p> + <p>The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:</p> -<pre class="hljs"><code>app.factory(<span class="hljs-string">'foo'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{ - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">privateMember</span><span class="hljs-params">()</span> </span>{ - <span class="hljs-comment">//body...</span> +<div class="highlight highlight-javascript"><pre>app.<span class="pl-c1">factory</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { + + <span class="pl-k">function</span> <span class="pl-en">privateMember</span>() { + <span class="pl-c">//body...</span> } - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">publicMember</span><span class="hljs-params">()</span> </span>{ - <span class="hljs-comment">//body...</span> - privateMember(); - <span class="hljs-comment">//body</span> + <span class="pl-k">function</span> <span class="pl-en">publicMember</span>() { + <span class="pl-c">//body...</span> + <span class="pl-c1">privateMember</span>(); + <span class="pl-c">//body</span> } - <span class="hljs-keyword">return</span> { - publicMember: publicMember + <span class="pl-k">return</span> { + publicMember<span class="pl-k">:</span> publicMember }; -});</code></pre><p>Once we want to inject <code>foo</code> inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.</p> -<h3 id="data-mapper">Data Mapper</h3> +});</pre></div> + +<p>Once we want to inject <code>foo</code> inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.</p> + +<h3> +<a id="data-mapper" class="anchor" href="#data-mapper" aria-hidden="true"><span class="octicon octicon-link"></span></a>Data Mapper</h3> + <blockquote> <p>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.</p> </blockquote> -<p class="img-container"><img src="./data-mapper.svg" alt="Data Mapper" title="Fig. 10"></p> + +<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/data-mapper.svg" alt="Data Mapper" title="Fig. 10"></p> + <p>As the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).</p> + <p>Usually, if we have RESTful API <code>$resource</code> will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.</p> + <p>For instance, lets assume we have application in which each user has:</p> -<ul class="list"> + +<ul> <li>name</li> <li>address</li> <li>list of friends</li> </ul> + <p>And our API has the methods:</p> -<ul class="list"> -<li><code>GET /user/:id</code> - returns the user's name and the address of given user</li> -<li><code>GET /friends/:id</code> - returns the list of friends of given user</li> + +<ul> +<li> +<code>GET /user/:id</code> - returns the user's name and the address of given user</li> +<li> +<code>GET /friends/:id</code> - returns the list of friends of given user</li> </ul> -<p>Possible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called <code>User</code>, which loads the user's friends when we request the user:</p> -<pre class="hljs"><code>app.factory(<span class="hljs-string">'User'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">($q)</span> </span>{ - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">User</span><span class="hljs-params">(name, address, friends)</span> </span>{ - <span class="hljs-keyword">this</span>.name = name; - <span class="hljs-keyword">this</span>.address = address; - <span class="hljs-keyword">this</span>.friends = friends; +<p>Possible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called <code>User</code>, which loads the user's friends when we request the user:</p> + +<div class="highlight highlight-javascript"><pre>app.<span class="pl-c1">factory</span>(<span class="pl-s"><span class="pl-pds">'</span>User<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$q</span>) { + + <span class="pl-k">function</span> <span class="pl-en">User</span>(<span class="pl-smi">name</span>, <span class="pl-smi">address</span>, <span class="pl-smi">friends</span>) { + <span class="pl-v">this</span>.<span class="pl-c1">name</span> <span class="pl-k">=</span> name; + <span class="pl-v">this</span>.<span class="pl-c1">address</span> <span class="pl-k">=</span> address; + <span class="pl-v">this</span>.<span class="pl-c1">friends</span> <span class="pl-k">=</span> friends; } - User.<span class="hljs-keyword">get</span> = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(params)</span> </span>{ - <span class="hljs-keyword">var</span> user = $http.<span class="hljs-keyword">get</span>(<span class="hljs-string">'/user/'</span> + params.id), - friends = $http.<span class="hljs-keyword">get</span>(<span class="hljs-string">'/friends/'</span> + params.id); - $q.all([user, friends]) - .then(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(user, friends)</span> </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> User(user.name, user.address, friends); + <span class="pl-c1">User</span>.<span class="pl-en">get</span> <span class="pl-k">=</span> <span class="pl-k">function</span> (<span class="pl-smi">params</span>) { + <span class="pl-k">var</span> user <span class="pl-k">=</span> $http.<span class="pl-c1">get</span>(<span class="pl-s"><span class="pl-pds">'</span>/user/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> params.<span class="pl-c1">id</span>), + friends <span class="pl-k">=</span> $http.<span class="pl-c1">get</span>(<span class="pl-s"><span class="pl-pds">'</span>/friends/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> params.<span class="pl-c1">id</span>); + $q.<span class="pl-c1">all</span>([user, friends]) + .<span class="pl-c1">then</span>(<span class="pl-k">function</span> (<span class="pl-smi">user</span>, <span class="pl-smi">friends</span>) { + <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-en">User</span>(user.<span class="pl-c1">name</span>, user.<span class="pl-c1">address</span>, friends); }); }; - <span class="hljs-keyword">return</span> User; -});</code></pre><p>This way we create pseudo-data mapper, which adapts our API according to the SPA requirements.</p> + <span class="pl-k">return</span> User; +});</pre></div> + +<p>This way we create pseudo-data mapper, which adapts our API according to the SPA requirements.</p> + <p>We can use the <code>User</code> service by:</p> -<pre class="hljs"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MainCtrl</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, User)</span> </span>{ - User.get({ id: <span class="hljs-number">1</span> }) - .then(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(data)</span> </span>{ - <span class="hljs-variable">$scope</span>.user = data; + +<div class="highlight highlight-javascript"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">User</span>) { + User.<span class="pl-c1">get</span>({ id<span class="pl-k">:</span> <span class="pl-c1">1</span> }) + .<span class="pl-c1">then</span>(<span class="pl-k">function</span> (<span class="pl-smi">data</span>) { + $scope.<span class="pl-c1">user</span> <span class="pl-k">=</span> data; }); -}</code></pre><p>And the following partial:</p> -<pre class="hljs"><code><span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span> - <span class="hljs-tag"><<span class="hljs-title">div</span>></span> - Name: </span><span class="hljs-expression">{{<span class="hljs-variable">user.name</span>}}</span><span class="xml"> - <span class="hljs-tag"></<span class="hljs-title">div</span>></span> - <span class="hljs-tag"><<span class="hljs-title">div</span>></span> - Address: </span><span class="hljs-expression">{{<span class="hljs-variable">user.address</span>}}</span><span class="xml"> - <span class="hljs-tag"></<span class="hljs-title">div</span>></span> - <span class="hljs-tag"><<span class="hljs-title">div</span>></span> +}</pre></div> + +<p>And the following partial:</p> + +<div class="highlight highlight-html"><pre><<span class="pl-ent">div</span>> + <<span class="pl-ent">div</span>> + Name: {{user.name}} + </<span class="pl-ent">div</span>> + <<span class="pl-ent">div</span>> + Address: {{user.address}} + </<span class="pl-ent">div</span>> + <<span class="pl-ent">div</span>> Friends with ids: - <span class="hljs-tag"><<span class="hljs-title">ul</span>></span> - <span class="hljs-tag"><<span class="hljs-title">li</span> <span class="hljs-attribute">ng-repeat</span>=<span class="hljs-value">"friend in user.friends"</span>></span></span><span class="hljs-expression">{{<span class="hljs-variable">friend</span>}}</span><span class="xml"><span class="hljs-tag"></<span class="hljs-title">li</span>></span> - <span class="hljs-tag"></<span class="hljs-title">ul</span>></span> - <span class="hljs-tag"></<span class="hljs-title">div</span>></span> -<span class="hljs-tag"></<span class="hljs-title">div</span>></span></span></code></pre><h3 id="observer-pattern-as-an-external-service">Observer Pattern as an External Service</h3> -<h5 id="about">About</h5> + <<span class="pl-ent">ul</span>> + <<span class="pl-ent">li</span> <span class="pl-e">ng-repeat</span>=<span class="pl-s"><span class="pl-pds">"</span>friend in user.friends<span class="pl-pds">"</span></span>>{{friend}}</<span class="pl-ent">li</span>> + </<span class="pl-ent">ul</span>> + </<span class="pl-ent">div</span>> +</<span class="pl-ent">div</span>></pre></div> + +<h3> +<a id="observer-pattern-as-an-external-service" class="anchor" href="#observer-pattern-as-an-external-service" aria-hidden="true"><span class="octicon octicon-link"></span></a>Observer Pattern as an External Service</h3> + +<h5> +<a id="about" class="anchor" href="#about" aria-hidden="true"><span class="octicon octicon-link"></span></a>About</h5> + <p>Below is an example taken from <a href="https://github.com/greglbd/angular-observer-pattern">here</a>. This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that <code>$scope.$watch</code> and more specific to a unique scope or object than $emit and $broadcast when used correctly.</p> + <p><strong>Use Case:</strong> You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.</p> -<h5 id="controller-example">Controller Example</h5> + +<h5> +<a id="controller-example" class="anchor" href="#controller-example" aria-hidden="true"><span class="octicon octicon-link"></span></a>Controller Example</h5> + <p>Below example shows how to attach, notify and detach an event.</p> -<pre class="hljs"><code>angular.module(<span class="hljs-string">'app.controllers'</span>) - .controller(<span class="hljs-string">'ObserverExample'</span>, ObserverExample); -ObserverExample.<span class="hljs-variable">$inject</span>= [<span class="hljs-string">'ObserverService'</span>, <span class="hljs-string">'$timeout'</span>]; -<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ObserverExample</span><span class="hljs-params">(ObserverService, <span class="hljs-variable">$timeout</span>)</span> </span>{ - <span class="hljs-keyword">var</span> vm = this; - <span class="hljs-keyword">var</span> id = <span class="hljs-string">'vm1'</span>; +<div class="highlight highlight-javascript"><pre>angular.<span class="pl-c1">module</span>(<span class="pl-s"><span class="pl-pds">'</span>app.controllers<span class="pl-pds">'</span></span>) + .<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>ObserverExample<span class="pl-pds">'</span></span>, ObserverExample); +ObserverExample.$inject<span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>ObserverService<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$timeout<span class="pl-pds">'</span></span>]; - ObserverService.attach(callbackFunction, <span class="hljs-string">'let_me_know'</span>, id) +<span class="pl-k">function</span> <span class="pl-en">ObserverExample</span>(<span class="pl-smi">ObserverService</span>, <span class="pl-smi">$timeout</span>) { + <span class="pl-k">var</span> vm <span class="pl-k">=</span> <span class="pl-v">this</span>; + <span class="pl-k">var</span> id <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>vm1<span class="pl-pds">'</span></span>; - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callbackFunction</span><span class="hljs-params">(params)</span></span>{ - console.log(<span class="hljs-string">'now i know'</span>); - ObserverService.detachByEvent(<span class="hljs-string">'let_me_know'</span>) + ObserverService.<span class="pl-c1">attach</span>(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) + + <span class="pl-k">function</span> <span class="pl-en">callbackFunction</span>(<span class="pl-smi">params</span>){ + <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); + ObserverService.<span class="pl-c1">detachByEvent</span>(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) } - <span class="hljs-variable">$timeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{ - ObserverService.notify(<span class="hljs-string">'let_me_know'</span>); - }, <span class="hljs-number">5000</span>); -}</code></pre><p>Alternative way to remove event</p> -<pre class="hljs"><code>angular.module(<span class="hljs-string">'app.controllers'</span>) - .controller(<span class="hljs-string">'ObserverExample'</span>, ObserverExample); -ObserverExample.<span class="hljs-variable">$inject</span>= [<span class="hljs-string">'ObserverService'</span>, <span class="hljs-string">'$timeout'</span>, <span class="hljs-string">'$scope'</span>]; - -<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ObserverExample</span><span class="hljs-params">(ObserverService, <span class="hljs-variable">$timeout</span>, <span class="hljs-variable">$scope</span>)</span> </span>{ - <span class="hljs-keyword">var</span> vm = this; - <span class="hljs-keyword">var</span> id = <span class="hljs-string">'vm1'</span>; - ObserverService.attach(callbackFunction, <span class="hljs-string">'let_me_know'</span>, id) - - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callbackFunction</span><span class="hljs-params">(params)</span></span>{ - console.log(<span class="hljs-string">'now i know'</span>); + $<span class="pl-c1">timeout</span>(<span class="pl-k">function</span>(){ + ObserverService.<span class="pl-c1">notify</span>(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>); + }, <span class="pl-c1">5000</span>); +}</pre></div> + +<p>Alternative way to remove event</p> + +<div class="highlight highlight-javascript"><pre>angular.<span class="pl-c1">module</span>(<span class="pl-s"><span class="pl-pds">'</span>app.controllers<span class="pl-pds">'</span></span>) + .<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>ObserverExample<span class="pl-pds">'</span></span>, ObserverExample); +ObserverExample.$inject<span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>ObserverService<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$timeout<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$scope<span class="pl-pds">'</span></span>]; + +<span class="pl-k">function</span> <span class="pl-en">ObserverExample</span>(<span class="pl-smi">ObserverService</span>, <span class="pl-smi">$timeout</span>, <span class="pl-smi">$scope</span>) { + <span class="pl-k">var</span> vm <span class="pl-k">=</span> <span class="pl-v">this</span>; + <span class="pl-k">var</span> id <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>vm1<span class="pl-pds">'</span></span>; + ObserverService.<span class="pl-c1">attach</span>(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) + + <span class="pl-k">function</span> <span class="pl-en">callbackFunction</span>(<span class="pl-smi">params</span>){ + <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); } - <span class="hljs-variable">$timeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{ - ObserverService.notify(<span class="hljs-string">'let_me_know'</span>); - }, <span class="hljs-number">5000</span>); + $<span class="pl-c1">timeout</span>(<span class="pl-k">function</span>(){ + ObserverService.<span class="pl-c1">notify</span>(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>); + }, <span class="pl-c1">5000</span>); - <span class="hljs-comment">// Cleanup listeners when this controller is destroyed</span> - <span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'$destroy'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span><span class="hljs-params">()</span> </span>{ - ObserverService.detachByEvent(<span class="hljs-string">'let_me_know'</span>) + <span class="pl-c">// Cleanup listeners when this controller is destroyed</span> + $scope.$<span class="pl-c1">on</span>(<span class="pl-s"><span class="pl-pds">'</span>$destroy<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> <span class="pl-en">handler</span>() { + ObserverService.<span class="pl-c1">detachByEvent</span>(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) }); -}</code></pre><h2 id="references">References</h2> -<ol class="list"> -<li><a href="https://en.wikipedia.org/wiki">Wikipedia</a>. The source of all brief descriptions of the design patterns is wikipedia.</li> -<li><a href="https://docs.angularjs.org">AngularJS' documentation</a></li> -<li><a href="https://github.com/angular/angular.js">AngularJS' git repository</a></li> +}</pre></div> + +<h2> +<a id="references" class="anchor" href="#references" aria-hidden="true"><span class="octicon octicon-link"></span></a>References</h2> + +<ol> +<li> +<a href="https://en.wikipedia.org/wiki">Wikipedia</a>. The source of all brief descriptions of the design patterns is wikipedia.</li> +<li><a href="https://docs.angularjs.org">AngularJS' documentation</a></li> +<li><a href="https://github.com/angular/angular.js">AngularJS' git repository</a></li> <li><a href="http://msdn.microsoft.com/en-us/library/ff649595.aspx">Page Controller</a></li> <li><a href="http://martinfowler.com/books/eaa.html">Patterns of Enterprise Application Architecture (P of EAA)</a></li> <li><a href="http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html">Using Dependancy Injection to Avoid Singletons</a></li> <li><a href="https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery">Why would one use the Publish/Subscribe pattern (in JS/jQuery)?</a></li> </ol> - </div> - </div> - </div> - <div id="sidebar"><ul class="nav nav-list"> - <li><a href="#angularjs-in-patterns" class="heading heading-1">AngularJS in Patterns</a></li> - <li><a href="#translations" class="heading heading-2">Translations</a></li> - <li><a href="#abstract" class="heading heading-2">Abstract</a></li> - <li><a href="#introduction" class="heading heading-2">Introduction</a></li> - <li><a href="#angularjs-overview" class="heading heading-2">AngularJS overview</a></li> - <li><a href="#partials" class="heading heading-3">Partials</a></li> - <li><a href="#controllers" class="heading heading-3">Controllers</a></li> - <li><a href="#scope" class="heading heading-3">Scope</a></li> - <li><a href="#directives" class="heading heading-3">Directives</a></li> - <li><a href="#filters" class="heading heading-3">Filters</a></li> - <li><a href="#services" class="heading heading-3">Services</a></li> - <li><a href="#angularjs-patterns" class="heading heading-2">AngularJS Patterns</a></li> - <li><a href="#services" class="heading heading-3">Services</a></li> - <li><a href="#singleton" class="heading heading-4">Singleton</a></li> - <li><a href="#factory-method" class="heading heading-4">Factory Method</a></li> - <li><a href="#decorator" class="heading heading-4">Decorator</a></li> - <li><a href="#facade" class="heading heading-4">Facade</a></li> - <li><a href="#proxy" class="heading heading-4">Proxy</a></li> - <li><a href="#active-record" class="heading heading-4">Active Record</a></li> - <li><a href="#intercepting-filters" class="heading heading-4">Intercepting Filters</a></li> - <li><a href="#directives" class="heading heading-3">Directives</a></li> - <li><a href="#composite" class="heading heading-4">Composite</a></li> - <li><a href="#interpreter" class="heading heading-3">Interpreter</a></li> - <li><a href="#template-view" class="heading heading-4">Template View</a></li> - <li><a href="#scope" class="heading heading-3">Scope</a></li> - <li><a href="#observer" class="heading heading-4">Observer</a></li> - <li><a href="#chain-of-responsibilities" class="heading heading-4">Chain of Responsibilities</a></li> - <li><a href="#command" class="heading heading-4">Command</a></li> - <li><a href="#controllers" class="heading heading-3">Controllers</a></li> - <li><a href="#page-controller" class="heading heading-4">Page Controller</a></li> - <li><a href="#others" class="heading heading-3">Others</a></li> - <li><a href="#module-pattern" class="heading heading-4">Module Pattern</a></li> - <li><a href="#data-mapper" class="heading heading-3">Data Mapper</a></li> - <li><a href="#observer-pattern-as-an-external-service" class="heading heading-3">Observer Pattern as an External Service</a></li> - <li><a href="#about" class="heading heading-5">About</a></li> - <li><a href="#controller-example" class="heading heading-5">Controller Example</a></li> - <li><a href="#references" class="heading heading-2">References</a></li> -</ul> - </div> - <div class="clear"> - </div> - - <div id="footer"> - <p>By <a href="http://blog.mgechev.com/">Minko Gechev</a>.</p> - </div> - </div> -</body> + <footer class="site-footer"> + <span class="site-footer-owner"><a href="https://github.com/mgechev/angularjs-in-patterns">AngularJS in Patterns</a> is maintained by <a href="https://github.com/mgechev">mgechev</a>.</span> + + <span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span> + </footer> + + </section> + + + </body> </html> diff --git a/params.json b/params.json new file mode 100644 index 0000000..fa9a014 --- /dev/null +++ b/params.json @@ -0,0 +1 @@ +{"name":"AngularJS in Patterns","tagline":"\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.","body":"# AngularJS in Patterns\r\n\r\n<!--toc-->\r\n\r\n## Table of Contents\r\n\r\n* [Translations](#translations)\r\n* [Abstract](#abstract)\r\n* [Introduction](#introduction)\r\n* [AngularJS overview](#angularjs-overview)\r\n * [Partials](#partials)\r\n * [Controllers](#controllers)\r\n * [Scope](#scope)\r\n * [Directives](#directives)\r\n * [Filters](#filters)\r\n * [Services](#services)\r\n* [AngularJS Patterns](#angularjs-patterns)\r\n * [Services](#services-1)\r\n * [Singleton](#singleton)\r\n * [Factory Method](#factory-method)\r\n * [Decorator](#decorator)\r\n * [Facade](#facade)\r\n * [Proxy](#proxy)\r\n * [Active Record](#active-record)\r\n * [Intercepting Filters](#intercepting-filters)\r\n * [Directives](#directives-1)\r\n * [Composite](#composite)\r\n * [Interpreter](#interpreter)\r\n * [Template View](#template-view)\r\n * [Scope](#scope-1)\r\n * [Observer](#observer)\r\n * [Chain of Responsibilities](#chain-of-responsibilities)\r\n * [Command](#command)\r\n * [Controller](#controller-1)\r\n * [Page Controller](#page-controller)\r\n * [Others](#others)\r\n * [Module Pattern](#module-pattern)\r\n * [Data Mapper](#data-mapper)\r\n * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n* [References](#references)\r\n\r\n<!--endtoc-->\r\n\r\n## Translations\r\n\r\n- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter)\r\n- [Russian Translation](http://habrahabr.ru/post/250149/)\r\n- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko)\r\n\r\n## Abstract\r\n\r\nOne of the best ways to learn something new is to see how the things you already know are used in it.\r\nThis document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns.\r\nThe goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.\r\n\r\n## Introduction\r\n\r\nThe document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.\r\n\r\nThe last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.\r\n\r\n## AngularJS overview\r\n\r\nAngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA).\r\nSPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand.\r\nSince most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:\r\n\r\n- two-way data binding\r\n- dependency injection\r\n- separation of concerns\r\n- testability\r\n- abstraction\r\n\r\nThe separation of concerns is achieved by dividing each AngularJS application into separate components, such as:\r\n\r\n- partials\r\n- controllers\r\n- directives\r\n- services\r\n- filters\r\n\r\nThese components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.\r\n\r\n### Partials\r\n\r\nThe partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).\r\n\r\nInitially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.\r\n\r\n**Sample partial**\r\n\r\n```HTML\r\n<html ng-app>\r\n <!-- Body tag augmented with ngController directive -->\r\n <body ng-controller=\"MyController\">\r\n <input ng-model=\"foo\" value=\"bar\">\r\n <!-- Button tag with ng-click directive, and\r\n string expression 'buttonText'\r\n wrapped in \"{{ }}\" markup -->\r\n <button ng-click=\"changeFoo()\">{{buttonText}}</button>\r\n <script src=\"angular.js\"></script>\r\n </body>\r\n</html>\r\n```\r\n\r\nWith AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked.\r\n\r\n### Controllers\r\n\r\nThe AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*.\r\n\r\n```JavaScript\r\nfunction MyController($scope) {\r\n $scope.buttonText = 'Click me to change foo!';\r\n $scope.foo = 42;\r\n\r\n $scope.changeFoo = function () {\r\n $scope.foo += 1;\r\n alert('Foo changed');\r\n };\r\n}\r\n```\r\n\r\nFor example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.\r\n\r\n1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding.\r\n2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`.\r\n\r\nAll the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones.\r\n\r\n### Scope\r\n\r\nIn AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.\r\n\r\nAnother important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.\r\n\r\nScope inheritance is illustrated in the following example:\r\n\r\n```HTML\r\n<div ng-controller=\"BaseCtrl\">\r\n <div id=\"child\" ng-controller=\"ChildCtrl\">\r\n <button id=\"parent-method\" ng-click=\"foo()\">Parent method</button>\r\n <button ng-click=\"bar()\">Child method</button>\r\n </div>\r\n</div>\r\n```\r\n\r\n```JavaScript\r\nfunction BaseCtrl($scope) {\r\n $scope.foo = function () {\r\n alert('Base foo');\r\n };\r\n}\r\n\r\nfunction ChildCtrl($scope) {\r\n $scope.bar = function () {\r\n alert('Child bar');\r\n };\r\n}\r\n```\r\n\r\nWith `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`.\r\n\r\n### Directives\r\n\r\nIn AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations.\r\nEach directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:\r\n\r\n- template\r\n- compile function\r\n- link function\r\n- etc...\r\n\r\nBy citing the name of the directives they can be used inside the declarative partials.\r\n\r\nExample:\r\n\r\n```JavaScript\r\nmyModule.directive('alertButton', function () {\r\n return {\r\n template: '<button ng-transclude></button>',\r\n scope: {\r\n content: '@'\r\n },\r\n replace: true,\r\n restrict: 'E',\r\n transclude: true,\r\n link: function (scope, el) {\r\n el.click(function () {\r\n alert(scope.content);\r\n });\r\n }\r\n };\r\n});\r\n```\r\n\r\n```HTML\r\n<alert-button content=\"42\">Click me</alert-button>\r\n```\r\n\r\nIn the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted.\r\n\r\nSince the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.\r\n\r\n### Filters\r\n\r\nThe filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection.\r\n\r\nHere is a definition of a sample filter, which changes the given string to uppercase:\r\n\r\n```JavaScript\r\nmyModule.filter('uppercase', function () {\r\n return function (str) {\r\n return (str || '').toUpperCase();\r\n };\r\n});\r\n```\r\n\r\nInside a partial this filter could be used using the Unix's piping syntax:\r\n\r\n```HTML\r\n<div>{{ name | uppercase }}</div>\r\n```\r\n\r\nInside a controller the filter could be used as follows:\r\n\r\n```JavaScript\r\nfunction MyCtrl(uppercaseFilter) {\r\n $scope.name = uppercaseFilter('foo'); //FOO\r\n}\r\n```\r\n\r\n### Services\r\n\r\nEvery piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too \"fat\" the repetitive code should be placed inside a service.\r\n\r\n```JavaScript\r\nmyModule.service('Developer', function () {\r\n this.name = 'Foo';\r\n this.motherLanguage = 'JavaScript';\r\n this.live = function () {\r\n while (true) {\r\n this.code();\r\n }\r\n };\r\n});\r\n```\r\n\r\nThe service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).\r\n\r\n```JavaScript\r\nfunction MyCtrl(Developer) {\r\n var developer = new Developer();\r\n developer.live();\r\n}\r\n```\r\n\r\n## AngularJS Patterns\r\n\r\nIn the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.\r\n\r\nIn the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.\r\n\r\n### Services\r\n\r\n#### Singleton\r\n\r\n>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.\r\n\r\nIn the UML diagram bellow is illustrated the singleton design pattern.\r\n\r\n\r\n\r\nWhen given dependency is required by any component, AngularJS resolves it using the following algorithm:\r\n\r\n- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).\r\n- If the dependency exists AngularJS pass it as parameter to the component, which requires it.\r\n- If the dependency does not exists:\r\n - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.\r\n - AngularJS caches it inside the hash map mentioned above.\r\n - AngularJS passes it as parameter to the component, which requires it.\r\n\r\nWe can take better look at the AngularJS' source code, which implements the method `getService`:\r\n\r\n```JavaScript\r\nfunction getService(serviceName) {\r\n if (cache.hasOwnProperty(serviceName)) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));\r\n }\r\n return cache[serviceName];\r\n } else {\r\n try {\r\n path.unshift(serviceName);\r\n cache[serviceName] = INSTANTIATING;\r\n return cache[serviceName] = factory(serviceName);\r\n } catch (err) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n delete cache[serviceName];\r\n }\r\n throw err;\r\n } finally {\r\n path.shift();\r\n }\r\n }\r\n}\r\n```\r\n\r\nWe can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`).\r\n\r\nThis way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:\r\n\r\n- It improves the testability of your source code\r\n- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)\r\n\r\nFor further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered.\r\n\r\n#### Factory Method\r\n\r\n>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.\r\n\r\n\r\n\r\nLets consider the following snippet:\r\n\r\n```JavaScript\r\nmyModule.config(function ($provide) {\r\n $provide.provider('foo', function () {\r\n var baz = 42;\r\n return {\r\n //Factory method\r\n $get: function (bar) {\r\n var baz = bar.baz();\r\n return {\r\n baz: baz\r\n };\r\n }\r\n };\r\n });\r\n});\r\n\r\n```\r\n\r\nIn the code above we use the `config` callback in order to define new \"provider\". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.\r\n\r\nEach service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.\r\n\r\nWe can dig a little bit deeper in AngularJS' implementation:\r\n\r\n```JavaScript\r\n//...\r\n\r\ncreateInternalInjector(instanceCache, function(servicename) {\r\n var provider = providerInjector.get(servicename + providerSuffix);\r\n return instanceInjector.invoke(provider.$get, provider, undefined, servicename);\r\n}, strictDi));\r\n\r\n//...\r\n\r\nfunction invoke(fn, self, locals, serviceName){\r\n if (typeof locals === 'string') {\r\n serviceName = locals;\r\n locals = null;\r\n }\r\n\r\n var args = [],\r\n $inject = annotate(fn, strictDi, serviceName),\r\n length, i,\r\n key;\r\n\r\n for(i = 0, length = $inject.length; i < length; i++) {\r\n key = $inject[i];\r\n if (typeof key !== 'string') {\r\n throw $injectorMinErr('itkn',\r\n 'Incorrect injection token! Expected service name as string, got {0}', key);\r\n }\r\n args.push(\r\n locals && locals.hasOwnProperty(key)\r\n ? locals[key]\r\n : getService(key)\r\n );\r\n }\r\n if (!fn.$inject) {\r\n // this means that we must be an array.\r\n fn = fn[length];\r\n }\r\n\r\n return fn.apply(self, args);\r\n}\r\n```\r\n\r\nFrom the example above we can notice how the `$get` method is actually used:\r\n\r\n```JavaScript\r\ninstanceInjector.invoke(provider.$get, provider, undefined, servicename)\r\n```\r\n\r\nThe snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.\r\n\r\nIf we think in terms of the UML diagram above we can call the provider a \"ConcreteCreator\" and the actual component, which is being created a \"Product\".\r\n\r\nThere are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:\r\n\r\n- The most appropriate moment, when the component needs to be instantiated\r\n- Resolving all the dependencies required by the component\r\n- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)\r\n\r\n#### Decorator\r\n\r\n>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.\r\n\r\n\r\n\r\nAngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create \"wrapper\" of any service you have previously defined or used by a third-party:\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function (foo) {\r\n foo.bar();\r\n});\r\n\r\nmyModule.factory('foo', function () {\r\n return {\r\n bar: function () {\r\n console.log('I\\'m bar');\r\n },\r\n baz: function () {\r\n console.log('I\\'m baz');\r\n }\r\n };\r\n});\r\n\r\nmyModule.config(function ($provide) {\r\n $provide.decorator('foo', function ($delegate) {\r\n var barBackup = $delegate.bar;\r\n $delegate.bar = function () {\r\n console.log('Decorated');\r\n barBackup.apply($delegate, arguments);\r\n };\r\n return $delegate;\r\n });\r\n});\r\n```\r\nThe example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `\"foo\"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.\r\nWe decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.\r\n\r\nUsing this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop).\r\n\r\n#### Facade\r\n\r\n>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:\r\n\r\n>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;\r\n\r\n>2. make the library more readable, for the same reason;\r\n\r\n>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;\r\n\r\n>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).\r\n\r\n\r\n\r\nThere are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.\r\n\r\nFor example, lets take a look how we can create an `XMLHttpRequest` POST request:\r\n\r\n```JavaScript\r\nvar http = new XMLHttpRequest(),\r\n url = '/example/new',\r\n params = encodeURIComponent(data);\r\nhttp.open(\"POST\", url, true);\r\n\r\nhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\r\nhttp.setRequestHeader(\"Content-length\", params.length);\r\nhttp.setRequestHeader(\"Connection\", \"close\");\r\n\r\nhttp.onreadystatechange = function () {\r\n if(http.readyState == 4 && http.status == 200) {\r\n alert(http.responseText);\r\n }\r\n}\r\nhttp.send(params);\r\n```\r\nBut if we want to post this data using the AngularJS' `$http` service we can:\r\n\r\n```JavaScript\r\n$http({\r\n method: 'POST',\r\n url: '/example/new',\r\n data: data\r\n})\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nor we can even:\r\n\r\n```JavaScript\r\n$http.post('/someUrl', data)\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nThe second option provides pre-configured version, which creates a HTTP POST request to the given URL.\r\n\r\nEven higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections.\r\n\r\n#### Proxy\r\n\r\n>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.\r\n\r\n\r\n\r\nWe can distinguish three different types of proxy:\r\n\r\n- Virtual Proxy\r\n- Remote Proxy\r\n- Protection Proxy\r\n\r\nIn this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.\r\n\r\nIn the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = User.get({ id: 42 });\r\nconsole.log(user); //{}\r\n```\r\n\r\n`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.\r\n\r\nHow does this works with AngularJS? Well, lets consider the following snippet:\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $resource) {\r\n var User = $resource('/users/:id'),\r\n $scope.user = User.get({ id: 42 });\r\n}\r\n```\r\n\r\n```html\r\n<span ng-bind=\"user.name\"></span>\r\n```\r\nInitially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view.\r\n\r\n#### Active Record\r\n\r\n>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.\r\n\r\n\r\n\r\nAngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.\r\n\r\nAccording to the AngularJS' documentation `$resource` is:\r\n\r\n>A factory which creates a resource object that lets you interact with RESTful server-side data sources.\r\n>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.\r\n\r\nHere is how `$resource` could be used:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = new User({\r\n name: 'foo',\r\n age : 42\r\n });\r\n\r\nuser.$save();\r\n```\r\n\r\nThe call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.\r\n\r\nThis way we can use the constructor function and its static methods by:\r\n\r\n```JavaScript\r\nUser.get({ userid: userid });\r\n```\r\n\r\nThe code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)).\r\n\r\nYou can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource).\r\n\r\nSince Martin Fowler states that\r\n\r\n> responsibility of the Active Record object is to take care of the communication with the databse in order to create...\r\n\r\n`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as \"Active Record like RESTful communication\".\r\n\r\n#### Intercepting Filters\r\n\r\n>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.\r\n\r\n\r\n\r\nIn some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.\r\n\r\nIn AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`.\r\n\r\n`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error.\r\n\r\nHere is a basic example how you can add interceptors using object literal:\r\n\r\n```JavaScript\r\n$httpProvider.interceptors.push(function($q, dependency1, dependency2) {\r\n return {\r\n 'request': function(config) {\r\n // same as above\r\n },\r\n 'response': function(response) {\r\n // same as above\r\n }\r\n };\r\n});\r\n```\r\n\r\n### Directives\r\n\r\n#### Composite\r\n\r\n>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to \"compose\" objects into tree structures to represent part-whole hierarchies.\r\n\r\n\r\n\r\nAccording to the Gang of Four, MVC is nothing more than combination of:\r\n\r\n- Strategy\r\n- Composite\r\n- Observer\r\n\r\nThey state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.\r\n\r\nLets look at the following example:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body>\r\n <zippy title=\"Zippy\">\r\n Zippy!\r\n </zippy>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nmyModule.directive('zippy', function () {\r\n return {\r\n restrict: 'E',\r\n template: '<div><div class=\"header\"></div><div class=\"content\" ng-transclude></div></div>',\r\n link: function (scope, el) {\r\n el.find('.header').click(function () {\r\n el.find('.content').toggle();\r\n });\r\n }\r\n }\r\n});\r\n```\r\n\r\nThis example defines a simple directive, which is a UI component. The defined component (called \"zippy\") has header and content. Click on its header toggles the visibility of the content.\r\n\r\nFrom the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on...\r\n\r\nIn the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.\r\n\r\n### Interpreter\r\n\r\n>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.\r\n\r\n\r\n\r\nBehind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript.\r\nThe main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:\r\n\r\n- may contain filters with UNIX like pipe syntax\r\n- don't throw any errors\r\n- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)\r\n- are evaluated in given context (the context of the current `$scope`)\r\n\r\nInside the `$parse` service are defined two main components:\r\n\r\n```JavaScript\r\n//Responsible for converting given string into tokens\r\nvar Lexer;\r\n//Responsible for parsing the tokens and evaluating the expression\r\nvar Parser;\r\n```\r\n\r\nOnce given expression have been tokenized it is cached internally, because of performance concerns.\r\n\r\nThe terminal expressions in the AngularJS DSL are defined as follows:\r\n\r\n```JavaScript\r\nvar OPERATORS = {\r\n /* jshint bitwise : false */\r\n 'null':function(){return null;},\r\n 'true':function(){return true;},\r\n 'false':function(){return false;},\r\n undefined:noop,\r\n '+':function(self, locals, a,b){\r\n //...\r\n },\r\n '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},\r\n '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},\r\n '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},\r\n '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},\r\n '=':noop,\r\n '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},\r\n '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},\r\n '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},\r\n '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},\r\n '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},\r\n '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},\r\n '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},\r\n '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},\r\n '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},\r\n '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},\r\n '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},\r\n '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},\r\n '!':function(self, locals, a){return !a(self, locals);}\r\n};\r\n```\r\n\r\nWe can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface.\r\n\r\nEach `Client` interprets given AngularJS expression in a specific context - specific scope.\r\n\r\nFew sample AngularJS expressions are:\r\n\r\n```JavaScript\r\n// toUpperCase filter is applied to the result of the expression\r\n// (foo) ? bar : baz\r\n(foo) ? bar : baz | toUpperCase\r\n```\r\n\r\n#### Template View\r\n\r\n> Renders information into HTML by embedding markers in an HTML page.\r\n\r\n\r\n\r\nThe dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.\r\n\r\nTemplates are very commonly used especially in the back-end.\r\nFor example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.\r\n\r\nFor JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript.\r\n\r\nFor example:\r\n\r\n```html\r\n<script type=\"template/mustache\">\r\n <h2>Names</h2>\r\n {{#names}}\r\n <strong>{{name}}</strong>\r\n {{/names}}\r\n</script>\r\n```\r\n\r\nThe template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.\r\n\r\nFor example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get:\r\n\r\n```html\r\n<h2>Names</h2>\r\n <strong>foo</strong>\r\n <strong>bar</strong>\r\n <strong>baz</strong>\r\n```\r\n\r\nAngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are.\r\nWhat AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.\r\n\r\nFor example:\r\n\r\n```html\r\n<ul ng-repeat=\"name in names\">\r\n <li>{{name}}</li>\r\n</ul>\r\n```\r\n\r\nin the context of the scope:\r\n\r\n```javascript\r\n$scope.names = ['foo', 'bar', 'baz'];\r\n```\r\n\r\nwill produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead.\r\n\r\n\r\n### Scope\r\n\r\n#### Observer\r\n\r\n>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.\r\n\r\n\r\n\r\nThere are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.\r\n\r\nEach AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$on('event-name', function handler() {\r\n //body\r\n });\r\n}\r\n```\r\n\r\nIn this way the current scope \"subscribes\" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.\r\n\r\nThe methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.\r\nFor example:\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$emit('event-name', { foo: 'bar' });\r\n}\r\n```\r\n\r\nThe scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.\r\n\r\nAnalogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.\r\nEach scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).\r\n\r\nIn the JavaScript community this pattern is better known as publish/subscribe.\r\n\r\nFor a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n\r\n#### Chain of Responsibilities\r\n\r\n>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.\r\n\r\n\r\n\r\nAs stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are \"isolated\", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.\r\n\r\nWhen `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:\r\n\r\n- Handle the event and pass it to the next scope in the chain\r\n- Handle the event and stop its propagation\r\n- Pass the event to the next scope in the chain without handling it\r\n- Stop the event propagation without handling it\r\n\r\nIn the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `\"foo received\"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback.\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function ($scope) {\r\n $scope.$on('foo', function () {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ParentCtrl', function ($scope) {\r\n $scope.$on('foo', function (e) {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ChildCtrl', function ($scope) {\r\n $scope.$emit('foo');\r\n});\r\n```\r\n\r\nThe different handlers from the UML diagram above are the different scopes, injected to the controllers.\r\n\r\n#### Command\r\n\r\n>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.\r\n\r\n\r\n\r\nBefore continuing with the application of the command pattern lets describe how AngularJS implements data binding.\r\n\r\nWhen we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can:\r\n\r\n```html\r\n<span ng-bind=\"foo\"></span>\r\n```\r\n\r\nNow each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:\r\n\r\n```html\r\n<span ng-bind=\"foo + ' ' + bar | uppercase\"></span>\r\n```\r\n\r\nIn the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene?\r\n\r\nEach `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch(\"foo + ' ' + bar | uppercase\", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.\r\n\r\nHere are the first a couple of lines of the implementation of `$watch`:\r\n\r\n```javascript\r\n$watch: function(watchExp, listener, objectEquality) {\r\n var scope = this,\r\n get = compileToFn(watchExp, 'watch'),\r\n array = scope.$$watchers,\r\n watcher = {\r\n fn: listener,\r\n last: initWatchVal,\r\n get: get,\r\n exp: watchExp,\r\n eq: !!objectEquality\r\n };\r\n//...\r\n```\r\n\r\nWe can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`\"$digest\"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`.\r\n\r\n### Controllers\r\n\r\n#### Page Controller\r\n\r\n>An object that handles a request for a specific page or action on a Web site. Martin Fowler\r\n\r\n\r\n\r\nAccording to [4](#references) the page controller:\r\n\r\n>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code\r\n\r\nSince there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.\r\n\r\nSimilarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.\r\n\r\nThe controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.\r\nHere is an example hierarchy between few controllers:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body ng-controller=\"MainCtrl\">\r\n <div ng-controller=\"ChildCtrl\">\r\n <span>{{user.name}}</span>\r\n <button ng-click=\"click()\">Click</button>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $location, User) {\r\n if (!User.isAuthenticated()) {\r\n $location.path('/unauthenticated');\r\n }\r\n}\r\n\r\nfunction ChildCtrl($scope, User) {\r\n $scope.click = function () {\r\n alert('You clicked me!');\r\n };\r\n $scope.user = User.get(0);\r\n}\r\n```\r\n\r\nThis example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.\r\n\r\nThe `ChildCtrl` is responsible for handling actions such as clicking the button with label `\"Click\"` and exposing the model to the view, by attaching it to the scope.\r\n\r\n### Others\r\n\r\n#### Module Pattern\r\n\r\nThis is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.\r\n\r\nUsing the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:\r\n\r\n```javascript\r\nvar Page = (function () {\r\n\r\n var title;\r\n\r\n function setTitle(t) {\r\n document.title = t;\r\n title = t;\r\n }\r\n\r\n function getTitle() {\r\n return title;\r\n }\r\n\r\n return {\r\n setTitle: setTitle,\r\n getTitle: getTitle\r\n };\r\n}());\r\n```\r\n\r\nIn the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.\r\n\r\nIn this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE.\r\n\r\nThe module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:\r\n\r\n```javascript\r\napp.factory('foo', function () {\r\n\r\n function privateMember() {\r\n //body...\r\n }\r\n\r\n function publicMember() {\r\n //body...\r\n privateMember();\r\n //body\r\n }\r\n\r\n return {\r\n publicMember: publicMember\r\n };\r\n});\r\n```\r\n\r\nOnce we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.\r\n\r\n### Data Mapper\r\n\r\n>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.\r\n\r\n\r\n\r\nAs the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).\r\n\r\nUsually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.\r\n\r\nFor instance, lets assume we have application in which each user has:\r\n\r\n- name\r\n- address\r\n- list of friends\r\n\r\nAnd our API has the methods:\r\n\r\n- `GET /user/:id` - returns the user's name and the address of given user\r\n- `GET /friends/:id` - returns the list of friends of given user\r\n\r\nPossible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:\r\n\r\n```javascript\r\napp.factory('User', function ($q) {\r\n\r\n function User(name, address, friends) {\r\n this.name = name;\r\n this.address = address;\r\n this.friends = friends;\r\n }\r\n\r\n User.get = function (params) {\r\n var user = $http.get('/user/' + params.id),\r\n friends = $http.get('/friends/' + params.id);\r\n $q.all([user, friends])\r\n .then(function (user, friends) {\r\n return new User(user.name, user.address, friends);\r\n });\r\n };\r\n return User;\r\n});\r\n```\r\n\r\nThis way we create pseudo-data mapper, which adapts our API according to the SPA requirements.\r\n\r\nWe can use the `User` service by:\r\n\r\n```javascript\r\nfunction MainCtrl($scope, User) {\r\n User.get({ id: 1 })\r\n .then(function (data) {\r\n $scope.user = data;\r\n });\r\n}\r\n```\r\n\r\nAnd the following partial:\r\n\r\n```html\r\n<div>\r\n <div>\r\n Name: {{user.name}}\r\n </div>\r\n <div>\r\n Address: {{user.address}}\r\n </div>\r\n <div>\r\n Friends with ids:\r\n <ul>\r\n <li ng-repeat=\"friend in user.friends\">{{friend}}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n```\r\n\r\n### Observer Pattern as an External Service\r\n\r\n##### About\r\n\r\nBelow is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.\r\n\r\n**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.\r\n\r\n##### Controller Example\r\n\r\nBelow example shows how to attach, notify and detach an event.\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout) {\r\n var vm = this;\r\n var id = 'vm1';\r\n\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n ObserverService.detachByEvent('let_me_know')\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n}\r\n```\r\nAlternative way to remove event\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout', '$scope'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout, $scope) {\r\n var vm = this;\r\n var id = 'vm1';\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n\r\n // Cleanup listeners when this controller is destroyed\r\n $scope.$on('$destroy', function handler() {\r\n ObserverService.detachByEvent('let_me_know')\r\n });\r\n}\r\n```\r\n\r\n## References\r\n\r\n1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.\r\n2. [AngularJS' documentation](https://docs.angularjs.org)\r\n3. [AngularJS' git repository](https://github.com/angular/angular.js)\r\n4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx)\r\n5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html)\r\n6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html)\r\n7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery)\r\n","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/stylesheets/github-light.css b/stylesheets/github-light.css new file mode 100644 index 0000000..872a6f4 --- /dev/null +++ b/stylesheets/github-light.css @@ -0,0 +1,116 @@ +/* + Copyright 2014 GitHub Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +.pl-c /* comment */ { + color: #969896; +} + +.pl-c1 /* constant, markup.raw, meta.diff.header, meta.module-reference, meta.property-name, support, support.constant, support.variable, variable.other.constant */, +.pl-s .pl-v /* string variable */ { + color: #0086b3; +} + +.pl-e /* entity */, +.pl-en /* entity.name */ { + color: #795da3; +} + +.pl-s .pl-s1 /* string source */, +.pl-smi /* storage.modifier.import, storage.modifier.package, storage.type.java, variable.other, variable.parameter.function */ { + color: #333; +} + +.pl-ent /* entity.name.tag */ { + color: #63a35c; +} + +.pl-k /* keyword, storage, storage.type */ { + color: #a71d5d; +} + +.pl-pds /* punctuation.definition.string, string.regexp.character-class */, +.pl-s /* string */, +.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, +.pl-sr /* string.regexp */, +.pl-sr .pl-cce /* string.regexp constant.character.escape */, +.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */, +.pl-sr .pl-sre /* string.regexp source.ruby.embedded */ { + color: #183691; +} + +.pl-v /* variable */ { + color: #ed6a43; +} + +.pl-id /* invalid.deprecated */ { + color: #b52a1d; +} + +.pl-ii /* invalid.illegal */ { + background-color: #b52a1d; + color: #f8f8f8; +} + +.pl-sr .pl-cce /* string.regexp constant.character.escape */ { + color: #63a35c; + font-weight: bold; +} + +.pl-ml /* markup.list */ { + color: #693a17; +} + +.pl-mh /* markup.heading */, +.pl-mh .pl-en /* markup.heading entity.name */, +.pl-ms /* meta.separator */ { + color: #1d3e81; + font-weight: bold; +} + +.pl-mq /* markup.quote */ { + color: #008080; +} + +.pl-mi /* markup.italic */ { + color: #333; + font-style: italic; +} + +.pl-mb /* markup.bold */ { + color: #333; + font-weight: bold; +} + +.pl-md /* markup.deleted, meta.diff.header.from-file */ { + background-color: #ffecec; + color: #bd2c00; +} + +.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ { + background-color: #eaffea; + color: #55a532; +} + +.pl-mdr /* meta.diff.range */ { + color: #795da3; + font-weight: bold; +} + +.pl-mo /* meta.output */ { + color: #1d3e81; +} + diff --git a/stylesheets/normalize.css b/stylesheets/normalize.css new file mode 100644 index 0000000..30366a6 --- /dev/null +++ b/stylesheets/normalize.css @@ -0,0 +1,424 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css new file mode 100644 index 0000000..b5f20c2 --- /dev/null +++ b/stylesheets/stylesheet.css @@ -0,0 +1,245 @@ +* { + box-sizing: border-box; } + +body { + padding: 0; + margin: 0; + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 1.5; + color: #606c71; } + +a { + color: #1e6bb8; + text-decoration: none; } + a:hover { + text-decoration: underline; } + +.btn { + display: inline-block; + margin-bottom: 1rem; + color: rgba(255, 255, 255, 0.7); + background-color: rgba(255, 255, 255, 0.08); + border-color: rgba(255, 255, 255, 0.2); + border-style: solid; + border-width: 1px; + border-radius: 0.3rem; + transition: color 0.2s, background-color 0.2s, border-color 0.2s; } + .btn + .btn { + margin-left: 1rem; } + +.btn:hover { + color: rgba(255, 255, 255, 0.8); + text-decoration: none; + background-color: rgba(255, 255, 255, 0.2); + border-color: rgba(255, 255, 255, 0.3); } + +@media screen and (min-width: 64em) { + .btn { + padding: 0.75rem 1rem; } } + +@media screen and (min-width: 42em) and (max-width: 64em) { + .btn { + padding: 0.6rem 0.9rem; + font-size: 0.9rem; } } + +@media screen and (max-width: 42em) { + .btn { + display: block; + width: 100%; + padding: 0.75rem; + font-size: 0.9rem; } + .btn + .btn { + margin-top: 1rem; + margin-left: 0; } } + +.page-header { + color: #fff; + text-align: center; + background-color: #159957; + background-image: linear-gradient(120deg, #155799, #159957); } + +@media screen and (min-width: 64em) { + .page-header { + padding: 5rem 6rem; } } + +@media screen and (min-width: 42em) and (max-width: 64em) { + .page-header { + padding: 3rem 4rem; } } + +@media screen and (max-width: 42em) { + .page-header { + padding: 2rem 1rem; } } + +.project-name { + margin-top: 0; + margin-bottom: 0.1rem; } + +@media screen and (min-width: 64em) { + .project-name { + font-size: 3.25rem; } } + +@media screen and (min-width: 42em) and (max-width: 64em) { + .project-name { + font-size: 2.25rem; } } + +@media screen and (max-width: 42em) { + .project-name { + font-size: 1.75rem; } } + +.project-tagline { + margin-bottom: 2rem; + font-weight: normal; + opacity: 0.7; } + +@media screen and (min-width: 64em) { + .project-tagline { + font-size: 1.25rem; } } + +@media screen and (min-width: 42em) and (max-width: 64em) { + .project-tagline { + font-size: 1.15rem; } } + +@media screen and (max-width: 42em) { + .project-tagline { + font-size: 1rem; } } + +.main-content :first-child { + margin-top: 0; } +.main-content img { + max-width: 100%; } +.main-content h1, .main-content h2, .main-content h3, .main-content h4, .main-content h5, .main-content h6 { + margin-top: 2rem; + margin-bottom: 1rem; + font-weight: normal; + color: #159957; } +.main-content p { + margin-bottom: 1em; } +.main-content code { + padding: 2px 4px; + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 0.9rem; + color: #383e41; + background-color: #f3f6fa; + border-radius: 0.3rem; } +.main-content pre { + padding: 0.8rem; + margin-top: 0; + margin-bottom: 1rem; + font: 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace; + color: #567482; + word-wrap: normal; + background-color: #f3f6fa; + border: solid 1px #dce6f0; + border-radius: 0.3rem; } + .main-content pre > code { + padding: 0; + margin: 0; + font-size: 0.9rem; + color: #567482; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; } +.main-content .highlight { + margin-bottom: 1rem; } + .main-content .highlight pre { + margin-bottom: 0; + word-break: normal; } +.main-content .highlight pre, .main-content pre { + padding: 0.8rem; + overflow: auto; + font-size: 0.9rem; + line-height: 1.45; + border-radius: 0.3rem; } +.main-content pre code, .main-content pre tt { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; } + .main-content pre code:before, .main-content pre code:after, .main-content pre tt:before, .main-content pre tt:after { + content: normal; } +.main-content ul, .main-content ol { + margin-top: 0; } +.main-content blockquote { + padding: 0 1rem; + margin-left: 0; + color: #819198; + border-left: 0.3rem solid #dce6f0; } + .main-content blockquote > :first-child { + margin-top: 0; } + .main-content blockquote > :last-child { + margin-bottom: 0; } +.main-content table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; } + .main-content table th { + font-weight: bold; } + .main-content table th, .main-content table td { + padding: 0.5rem 1rem; + border: 1px solid #e9ebec; } +.main-content dl { + padding: 0; } + .main-content dl dt { + padding: 0; + margin-top: 1rem; + font-size: 1rem; + font-weight: bold; } + .main-content dl dd { + padding: 0; + margin-bottom: 1rem; } +.main-content hr { + height: 2px; + padding: 0; + margin: 1rem 0; + background-color: #eff0f1; + border: 0; } + +@media screen and (min-width: 64em) { + .main-content { + max-width: 64rem; + padding: 2rem 6rem; + margin: 0 auto; + font-size: 1.1rem; } } + +@media screen and (min-width: 42em) and (max-width: 64em) { + .main-content { + padding: 2rem 4rem; + font-size: 1.1rem; } } + +@media screen and (max-width: 42em) { + .main-content { + padding: 2rem 1rem; + font-size: 1rem; } } + +.site-footer { + padding-top: 2rem; + margin-top: 2rem; + border-top: solid 1px #eff0f1; } + +.site-footer-owner { + display: block; + font-weight: bold; } + +.site-footer-credits { + color: #819198; } + +@media screen and (min-width: 64em) { + .site-footer { + font-size: 1rem; } } + +@media screen and (min-width: 42em) and (max-width: 64em) { + .site-footer { + font-size: 1rem; } } + +@media screen and (max-width: 42em) { + .site-footer { + font-size: 0.9rem; } } From c064027fa13593d2923778b0c7a10d7ce672a95f Mon Sep 17 00:00:00 2001 From: Minko Gechev <mgechev@gmail.com> Date: Tue, 1 Sep 2015 17:02:45 +0300 Subject: [PATCH 14/19] Create gh-pages branch via GitHub --- index.html | 12 +++++++++++- params.json | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 848b751..7060d8d 100644 --- a/index.html +++ b/index.html @@ -1254,6 +1254,16 @@ <h2> </section> - + <script type="text/javascript"> + var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); + document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); + </script> + <script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-18060688-20"); + pageTracker._trackPageview(); + } catch(err) {} + </script> + </body> </html> diff --git a/params.json b/params.json index fa9a014..50f31d4 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"AngularJS in Patterns","tagline":"\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.","body":"# AngularJS in Patterns\r\n\r\n<!--toc-->\r\n\r\n## Table of Contents\r\n\r\n* [Translations](#translations)\r\n* [Abstract](#abstract)\r\n* [Introduction](#introduction)\r\n* [AngularJS overview](#angularjs-overview)\r\n * [Partials](#partials)\r\n * [Controllers](#controllers)\r\n * [Scope](#scope)\r\n * [Directives](#directives)\r\n * [Filters](#filters)\r\n * [Services](#services)\r\n* [AngularJS Patterns](#angularjs-patterns)\r\n * [Services](#services-1)\r\n * [Singleton](#singleton)\r\n * [Factory Method](#factory-method)\r\n * [Decorator](#decorator)\r\n * [Facade](#facade)\r\n * [Proxy](#proxy)\r\n * [Active Record](#active-record)\r\n * [Intercepting Filters](#intercepting-filters)\r\n * [Directives](#directives-1)\r\n * [Composite](#composite)\r\n * [Interpreter](#interpreter)\r\n * [Template View](#template-view)\r\n * [Scope](#scope-1)\r\n * [Observer](#observer)\r\n * [Chain of Responsibilities](#chain-of-responsibilities)\r\n * [Command](#command)\r\n * [Controller](#controller-1)\r\n * [Page Controller](#page-controller)\r\n * [Others](#others)\r\n * [Module Pattern](#module-pattern)\r\n * [Data Mapper](#data-mapper)\r\n * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n* [References](#references)\r\n\r\n<!--endtoc-->\r\n\r\n## Translations\r\n\r\n- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter)\r\n- [Russian Translation](http://habrahabr.ru/post/250149/)\r\n- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko)\r\n\r\n## Abstract\r\n\r\nOne of the best ways to learn something new is to see how the things you already know are used in it.\r\nThis document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns.\r\nThe goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.\r\n\r\n## Introduction\r\n\r\nThe document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.\r\n\r\nThe last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.\r\n\r\n## AngularJS overview\r\n\r\nAngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA).\r\nSPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand.\r\nSince most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:\r\n\r\n- two-way data binding\r\n- dependency injection\r\n- separation of concerns\r\n- testability\r\n- abstraction\r\n\r\nThe separation of concerns is achieved by dividing each AngularJS application into separate components, such as:\r\n\r\n- partials\r\n- controllers\r\n- directives\r\n- services\r\n- filters\r\n\r\nThese components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.\r\n\r\n### Partials\r\n\r\nThe partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).\r\n\r\nInitially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.\r\n\r\n**Sample partial**\r\n\r\n```HTML\r\n<html ng-app>\r\n <!-- Body tag augmented with ngController directive -->\r\n <body ng-controller=\"MyController\">\r\n <input ng-model=\"foo\" value=\"bar\">\r\n <!-- Button tag with ng-click directive, and\r\n string expression 'buttonText'\r\n wrapped in \"{{ }}\" markup -->\r\n <button ng-click=\"changeFoo()\">{{buttonText}}</button>\r\n <script src=\"angular.js\"></script>\r\n </body>\r\n</html>\r\n```\r\n\r\nWith AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked.\r\n\r\n### Controllers\r\n\r\nThe AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*.\r\n\r\n```JavaScript\r\nfunction MyController($scope) {\r\n $scope.buttonText = 'Click me to change foo!';\r\n $scope.foo = 42;\r\n\r\n $scope.changeFoo = function () {\r\n $scope.foo += 1;\r\n alert('Foo changed');\r\n };\r\n}\r\n```\r\n\r\nFor example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.\r\n\r\n1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding.\r\n2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`.\r\n\r\nAll the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones.\r\n\r\n### Scope\r\n\r\nIn AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.\r\n\r\nAnother important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.\r\n\r\nScope inheritance is illustrated in the following example:\r\n\r\n```HTML\r\n<div ng-controller=\"BaseCtrl\">\r\n <div id=\"child\" ng-controller=\"ChildCtrl\">\r\n <button id=\"parent-method\" ng-click=\"foo()\">Parent method</button>\r\n <button ng-click=\"bar()\">Child method</button>\r\n </div>\r\n</div>\r\n```\r\n\r\n```JavaScript\r\nfunction BaseCtrl($scope) {\r\n $scope.foo = function () {\r\n alert('Base foo');\r\n };\r\n}\r\n\r\nfunction ChildCtrl($scope) {\r\n $scope.bar = function () {\r\n alert('Child bar');\r\n };\r\n}\r\n```\r\n\r\nWith `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`.\r\n\r\n### Directives\r\n\r\nIn AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations.\r\nEach directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:\r\n\r\n- template\r\n- compile function\r\n- link function\r\n- etc...\r\n\r\nBy citing the name of the directives they can be used inside the declarative partials.\r\n\r\nExample:\r\n\r\n```JavaScript\r\nmyModule.directive('alertButton', function () {\r\n return {\r\n template: '<button ng-transclude></button>',\r\n scope: {\r\n content: '@'\r\n },\r\n replace: true,\r\n restrict: 'E',\r\n transclude: true,\r\n link: function (scope, el) {\r\n el.click(function () {\r\n alert(scope.content);\r\n });\r\n }\r\n };\r\n});\r\n```\r\n\r\n```HTML\r\n<alert-button content=\"42\">Click me</alert-button>\r\n```\r\n\r\nIn the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted.\r\n\r\nSince the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.\r\n\r\n### Filters\r\n\r\nThe filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection.\r\n\r\nHere is a definition of a sample filter, which changes the given string to uppercase:\r\n\r\n```JavaScript\r\nmyModule.filter('uppercase', function () {\r\n return function (str) {\r\n return (str || '').toUpperCase();\r\n };\r\n});\r\n```\r\n\r\nInside a partial this filter could be used using the Unix's piping syntax:\r\n\r\n```HTML\r\n<div>{{ name | uppercase }}</div>\r\n```\r\n\r\nInside a controller the filter could be used as follows:\r\n\r\n```JavaScript\r\nfunction MyCtrl(uppercaseFilter) {\r\n $scope.name = uppercaseFilter('foo'); //FOO\r\n}\r\n```\r\n\r\n### Services\r\n\r\nEvery piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too \"fat\" the repetitive code should be placed inside a service.\r\n\r\n```JavaScript\r\nmyModule.service('Developer', function () {\r\n this.name = 'Foo';\r\n this.motherLanguage = 'JavaScript';\r\n this.live = function () {\r\n while (true) {\r\n this.code();\r\n }\r\n };\r\n});\r\n```\r\n\r\nThe service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).\r\n\r\n```JavaScript\r\nfunction MyCtrl(Developer) {\r\n var developer = new Developer();\r\n developer.live();\r\n}\r\n```\r\n\r\n## AngularJS Patterns\r\n\r\nIn the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.\r\n\r\nIn the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.\r\n\r\n### Services\r\n\r\n#### Singleton\r\n\r\n>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.\r\n\r\nIn the UML diagram bellow is illustrated the singleton design pattern.\r\n\r\n\r\n\r\nWhen given dependency is required by any component, AngularJS resolves it using the following algorithm:\r\n\r\n- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).\r\n- If the dependency exists AngularJS pass it as parameter to the component, which requires it.\r\n- If the dependency does not exists:\r\n - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.\r\n - AngularJS caches it inside the hash map mentioned above.\r\n - AngularJS passes it as parameter to the component, which requires it.\r\n\r\nWe can take better look at the AngularJS' source code, which implements the method `getService`:\r\n\r\n```JavaScript\r\nfunction getService(serviceName) {\r\n if (cache.hasOwnProperty(serviceName)) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));\r\n }\r\n return cache[serviceName];\r\n } else {\r\n try {\r\n path.unshift(serviceName);\r\n cache[serviceName] = INSTANTIATING;\r\n return cache[serviceName] = factory(serviceName);\r\n } catch (err) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n delete cache[serviceName];\r\n }\r\n throw err;\r\n } finally {\r\n path.shift();\r\n }\r\n }\r\n}\r\n```\r\n\r\nWe can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`).\r\n\r\nThis way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:\r\n\r\n- It improves the testability of your source code\r\n- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)\r\n\r\nFor further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered.\r\n\r\n#### Factory Method\r\n\r\n>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.\r\n\r\n\r\n\r\nLets consider the following snippet:\r\n\r\n```JavaScript\r\nmyModule.config(function ($provide) {\r\n $provide.provider('foo', function () {\r\n var baz = 42;\r\n return {\r\n //Factory method\r\n $get: function (bar) {\r\n var baz = bar.baz();\r\n return {\r\n baz: baz\r\n };\r\n }\r\n };\r\n });\r\n});\r\n\r\n```\r\n\r\nIn the code above we use the `config` callback in order to define new \"provider\". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.\r\n\r\nEach service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.\r\n\r\nWe can dig a little bit deeper in AngularJS' implementation:\r\n\r\n```JavaScript\r\n//...\r\n\r\ncreateInternalInjector(instanceCache, function(servicename) {\r\n var provider = providerInjector.get(servicename + providerSuffix);\r\n return instanceInjector.invoke(provider.$get, provider, undefined, servicename);\r\n}, strictDi));\r\n\r\n//...\r\n\r\nfunction invoke(fn, self, locals, serviceName){\r\n if (typeof locals === 'string') {\r\n serviceName = locals;\r\n locals = null;\r\n }\r\n\r\n var args = [],\r\n $inject = annotate(fn, strictDi, serviceName),\r\n length, i,\r\n key;\r\n\r\n for(i = 0, length = $inject.length; i < length; i++) {\r\n key = $inject[i];\r\n if (typeof key !== 'string') {\r\n throw $injectorMinErr('itkn',\r\n 'Incorrect injection token! Expected service name as string, got {0}', key);\r\n }\r\n args.push(\r\n locals && locals.hasOwnProperty(key)\r\n ? locals[key]\r\n : getService(key)\r\n );\r\n }\r\n if (!fn.$inject) {\r\n // this means that we must be an array.\r\n fn = fn[length];\r\n }\r\n\r\n return fn.apply(self, args);\r\n}\r\n```\r\n\r\nFrom the example above we can notice how the `$get` method is actually used:\r\n\r\n```JavaScript\r\ninstanceInjector.invoke(provider.$get, provider, undefined, servicename)\r\n```\r\n\r\nThe snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.\r\n\r\nIf we think in terms of the UML diagram above we can call the provider a \"ConcreteCreator\" and the actual component, which is being created a \"Product\".\r\n\r\nThere are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:\r\n\r\n- The most appropriate moment, when the component needs to be instantiated\r\n- Resolving all the dependencies required by the component\r\n- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)\r\n\r\n#### Decorator\r\n\r\n>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.\r\n\r\n\r\n\r\nAngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create \"wrapper\" of any service you have previously defined or used by a third-party:\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function (foo) {\r\n foo.bar();\r\n});\r\n\r\nmyModule.factory('foo', function () {\r\n return {\r\n bar: function () {\r\n console.log('I\\'m bar');\r\n },\r\n baz: function () {\r\n console.log('I\\'m baz');\r\n }\r\n };\r\n});\r\n\r\nmyModule.config(function ($provide) {\r\n $provide.decorator('foo', function ($delegate) {\r\n var barBackup = $delegate.bar;\r\n $delegate.bar = function () {\r\n console.log('Decorated');\r\n barBackup.apply($delegate, arguments);\r\n };\r\n return $delegate;\r\n });\r\n});\r\n```\r\nThe example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `\"foo\"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.\r\nWe decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.\r\n\r\nUsing this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop).\r\n\r\n#### Facade\r\n\r\n>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:\r\n\r\n>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;\r\n\r\n>2. make the library more readable, for the same reason;\r\n\r\n>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;\r\n\r\n>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).\r\n\r\n\r\n\r\nThere are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.\r\n\r\nFor example, lets take a look how we can create an `XMLHttpRequest` POST request:\r\n\r\n```JavaScript\r\nvar http = new XMLHttpRequest(),\r\n url = '/example/new',\r\n params = encodeURIComponent(data);\r\nhttp.open(\"POST\", url, true);\r\n\r\nhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\r\nhttp.setRequestHeader(\"Content-length\", params.length);\r\nhttp.setRequestHeader(\"Connection\", \"close\");\r\n\r\nhttp.onreadystatechange = function () {\r\n if(http.readyState == 4 && http.status == 200) {\r\n alert(http.responseText);\r\n }\r\n}\r\nhttp.send(params);\r\n```\r\nBut if we want to post this data using the AngularJS' `$http` service we can:\r\n\r\n```JavaScript\r\n$http({\r\n method: 'POST',\r\n url: '/example/new',\r\n data: data\r\n})\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nor we can even:\r\n\r\n```JavaScript\r\n$http.post('/someUrl', data)\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nThe second option provides pre-configured version, which creates a HTTP POST request to the given URL.\r\n\r\nEven higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections.\r\n\r\n#### Proxy\r\n\r\n>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.\r\n\r\n\r\n\r\nWe can distinguish three different types of proxy:\r\n\r\n- Virtual Proxy\r\n- Remote Proxy\r\n- Protection Proxy\r\n\r\nIn this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.\r\n\r\nIn the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = User.get({ id: 42 });\r\nconsole.log(user); //{}\r\n```\r\n\r\n`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.\r\n\r\nHow does this works with AngularJS? Well, lets consider the following snippet:\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $resource) {\r\n var User = $resource('/users/:id'),\r\n $scope.user = User.get({ id: 42 });\r\n}\r\n```\r\n\r\n```html\r\n<span ng-bind=\"user.name\"></span>\r\n```\r\nInitially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view.\r\n\r\n#### Active Record\r\n\r\n>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.\r\n\r\n\r\n\r\nAngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.\r\n\r\nAccording to the AngularJS' documentation `$resource` is:\r\n\r\n>A factory which creates a resource object that lets you interact with RESTful server-side data sources.\r\n>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.\r\n\r\nHere is how `$resource` could be used:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = new User({\r\n name: 'foo',\r\n age : 42\r\n });\r\n\r\nuser.$save();\r\n```\r\n\r\nThe call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.\r\n\r\nThis way we can use the constructor function and its static methods by:\r\n\r\n```JavaScript\r\nUser.get({ userid: userid });\r\n```\r\n\r\nThe code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)).\r\n\r\nYou can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource).\r\n\r\nSince Martin Fowler states that\r\n\r\n> responsibility of the Active Record object is to take care of the communication with the databse in order to create...\r\n\r\n`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as \"Active Record like RESTful communication\".\r\n\r\n#### Intercepting Filters\r\n\r\n>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.\r\n\r\n\r\n\r\nIn some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.\r\n\r\nIn AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`.\r\n\r\n`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error.\r\n\r\nHere is a basic example how you can add interceptors using object literal:\r\n\r\n```JavaScript\r\n$httpProvider.interceptors.push(function($q, dependency1, dependency2) {\r\n return {\r\n 'request': function(config) {\r\n // same as above\r\n },\r\n 'response': function(response) {\r\n // same as above\r\n }\r\n };\r\n});\r\n```\r\n\r\n### Directives\r\n\r\n#### Composite\r\n\r\n>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to \"compose\" objects into tree structures to represent part-whole hierarchies.\r\n\r\n\r\n\r\nAccording to the Gang of Four, MVC is nothing more than combination of:\r\n\r\n- Strategy\r\n- Composite\r\n- Observer\r\n\r\nThey state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.\r\n\r\nLets look at the following example:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body>\r\n <zippy title=\"Zippy\">\r\n Zippy!\r\n </zippy>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nmyModule.directive('zippy', function () {\r\n return {\r\n restrict: 'E',\r\n template: '<div><div class=\"header\"></div><div class=\"content\" ng-transclude></div></div>',\r\n link: function (scope, el) {\r\n el.find('.header').click(function () {\r\n el.find('.content').toggle();\r\n });\r\n }\r\n }\r\n});\r\n```\r\n\r\nThis example defines a simple directive, which is a UI component. The defined component (called \"zippy\") has header and content. Click on its header toggles the visibility of the content.\r\n\r\nFrom the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on...\r\n\r\nIn the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.\r\n\r\n### Interpreter\r\n\r\n>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.\r\n\r\n\r\n\r\nBehind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript.\r\nThe main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:\r\n\r\n- may contain filters with UNIX like pipe syntax\r\n- don't throw any errors\r\n- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)\r\n- are evaluated in given context (the context of the current `$scope`)\r\n\r\nInside the `$parse` service are defined two main components:\r\n\r\n```JavaScript\r\n//Responsible for converting given string into tokens\r\nvar Lexer;\r\n//Responsible for parsing the tokens and evaluating the expression\r\nvar Parser;\r\n```\r\n\r\nOnce given expression have been tokenized it is cached internally, because of performance concerns.\r\n\r\nThe terminal expressions in the AngularJS DSL are defined as follows:\r\n\r\n```JavaScript\r\nvar OPERATORS = {\r\n /* jshint bitwise : false */\r\n 'null':function(){return null;},\r\n 'true':function(){return true;},\r\n 'false':function(){return false;},\r\n undefined:noop,\r\n '+':function(self, locals, a,b){\r\n //...\r\n },\r\n '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},\r\n '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},\r\n '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},\r\n '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},\r\n '=':noop,\r\n '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},\r\n '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},\r\n '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},\r\n '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},\r\n '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},\r\n '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},\r\n '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},\r\n '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},\r\n '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},\r\n '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},\r\n '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},\r\n '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},\r\n '!':function(self, locals, a){return !a(self, locals);}\r\n};\r\n```\r\n\r\nWe can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface.\r\n\r\nEach `Client` interprets given AngularJS expression in a specific context - specific scope.\r\n\r\nFew sample AngularJS expressions are:\r\n\r\n```JavaScript\r\n// toUpperCase filter is applied to the result of the expression\r\n// (foo) ? bar : baz\r\n(foo) ? bar : baz | toUpperCase\r\n```\r\n\r\n#### Template View\r\n\r\n> Renders information into HTML by embedding markers in an HTML page.\r\n\r\n\r\n\r\nThe dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.\r\n\r\nTemplates are very commonly used especially in the back-end.\r\nFor example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.\r\n\r\nFor JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript.\r\n\r\nFor example:\r\n\r\n```html\r\n<script type=\"template/mustache\">\r\n <h2>Names</h2>\r\n {{#names}}\r\n <strong>{{name}}</strong>\r\n {{/names}}\r\n</script>\r\n```\r\n\r\nThe template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.\r\n\r\nFor example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get:\r\n\r\n```html\r\n<h2>Names</h2>\r\n <strong>foo</strong>\r\n <strong>bar</strong>\r\n <strong>baz</strong>\r\n```\r\n\r\nAngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are.\r\nWhat AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.\r\n\r\nFor example:\r\n\r\n```html\r\n<ul ng-repeat=\"name in names\">\r\n <li>{{name}}</li>\r\n</ul>\r\n```\r\n\r\nin the context of the scope:\r\n\r\n```javascript\r\n$scope.names = ['foo', 'bar', 'baz'];\r\n```\r\n\r\nwill produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead.\r\n\r\n\r\n### Scope\r\n\r\n#### Observer\r\n\r\n>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.\r\n\r\n\r\n\r\nThere are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.\r\n\r\nEach AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$on('event-name', function handler() {\r\n //body\r\n });\r\n}\r\n```\r\n\r\nIn this way the current scope \"subscribes\" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.\r\n\r\nThe methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.\r\nFor example:\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$emit('event-name', { foo: 'bar' });\r\n}\r\n```\r\n\r\nThe scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.\r\n\r\nAnalogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.\r\nEach scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).\r\n\r\nIn the JavaScript community this pattern is better known as publish/subscribe.\r\n\r\nFor a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n\r\n#### Chain of Responsibilities\r\n\r\n>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.\r\n\r\n\r\n\r\nAs stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are \"isolated\", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.\r\n\r\nWhen `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:\r\n\r\n- Handle the event and pass it to the next scope in the chain\r\n- Handle the event and stop its propagation\r\n- Pass the event to the next scope in the chain without handling it\r\n- Stop the event propagation without handling it\r\n\r\nIn the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `\"foo received\"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback.\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function ($scope) {\r\n $scope.$on('foo', function () {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ParentCtrl', function ($scope) {\r\n $scope.$on('foo', function (e) {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ChildCtrl', function ($scope) {\r\n $scope.$emit('foo');\r\n});\r\n```\r\n\r\nThe different handlers from the UML diagram above are the different scopes, injected to the controllers.\r\n\r\n#### Command\r\n\r\n>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.\r\n\r\n\r\n\r\nBefore continuing with the application of the command pattern lets describe how AngularJS implements data binding.\r\n\r\nWhen we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can:\r\n\r\n```html\r\n<span ng-bind=\"foo\"></span>\r\n```\r\n\r\nNow each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:\r\n\r\n```html\r\n<span ng-bind=\"foo + ' ' + bar | uppercase\"></span>\r\n```\r\n\r\nIn the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene?\r\n\r\nEach `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch(\"foo + ' ' + bar | uppercase\", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.\r\n\r\nHere are the first a couple of lines of the implementation of `$watch`:\r\n\r\n```javascript\r\n$watch: function(watchExp, listener, objectEquality) {\r\n var scope = this,\r\n get = compileToFn(watchExp, 'watch'),\r\n array = scope.$$watchers,\r\n watcher = {\r\n fn: listener,\r\n last: initWatchVal,\r\n get: get,\r\n exp: watchExp,\r\n eq: !!objectEquality\r\n };\r\n//...\r\n```\r\n\r\nWe can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`\"$digest\"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`.\r\n\r\n### Controllers\r\n\r\n#### Page Controller\r\n\r\n>An object that handles a request for a specific page or action on a Web site. Martin Fowler\r\n\r\n\r\n\r\nAccording to [4](#references) the page controller:\r\n\r\n>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code\r\n\r\nSince there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.\r\n\r\nSimilarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.\r\n\r\nThe controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.\r\nHere is an example hierarchy between few controllers:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body ng-controller=\"MainCtrl\">\r\n <div ng-controller=\"ChildCtrl\">\r\n <span>{{user.name}}</span>\r\n <button ng-click=\"click()\">Click</button>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $location, User) {\r\n if (!User.isAuthenticated()) {\r\n $location.path('/unauthenticated');\r\n }\r\n}\r\n\r\nfunction ChildCtrl($scope, User) {\r\n $scope.click = function () {\r\n alert('You clicked me!');\r\n };\r\n $scope.user = User.get(0);\r\n}\r\n```\r\n\r\nThis example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.\r\n\r\nThe `ChildCtrl` is responsible for handling actions such as clicking the button with label `\"Click\"` and exposing the model to the view, by attaching it to the scope.\r\n\r\n### Others\r\n\r\n#### Module Pattern\r\n\r\nThis is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.\r\n\r\nUsing the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:\r\n\r\n```javascript\r\nvar Page = (function () {\r\n\r\n var title;\r\n\r\n function setTitle(t) {\r\n document.title = t;\r\n title = t;\r\n }\r\n\r\n function getTitle() {\r\n return title;\r\n }\r\n\r\n return {\r\n setTitle: setTitle,\r\n getTitle: getTitle\r\n };\r\n}());\r\n```\r\n\r\nIn the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.\r\n\r\nIn this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE.\r\n\r\nThe module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:\r\n\r\n```javascript\r\napp.factory('foo', function () {\r\n\r\n function privateMember() {\r\n //body...\r\n }\r\n\r\n function publicMember() {\r\n //body...\r\n privateMember();\r\n //body\r\n }\r\n\r\n return {\r\n publicMember: publicMember\r\n };\r\n});\r\n```\r\n\r\nOnce we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.\r\n\r\n### Data Mapper\r\n\r\n>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.\r\n\r\n\r\n\r\nAs the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).\r\n\r\nUsually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.\r\n\r\nFor instance, lets assume we have application in which each user has:\r\n\r\n- name\r\n- address\r\n- list of friends\r\n\r\nAnd our API has the methods:\r\n\r\n- `GET /user/:id` - returns the user's name and the address of given user\r\n- `GET /friends/:id` - returns the list of friends of given user\r\n\r\nPossible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:\r\n\r\n```javascript\r\napp.factory('User', function ($q) {\r\n\r\n function User(name, address, friends) {\r\n this.name = name;\r\n this.address = address;\r\n this.friends = friends;\r\n }\r\n\r\n User.get = function (params) {\r\n var user = $http.get('/user/' + params.id),\r\n friends = $http.get('/friends/' + params.id);\r\n $q.all([user, friends])\r\n .then(function (user, friends) {\r\n return new User(user.name, user.address, friends);\r\n });\r\n };\r\n return User;\r\n});\r\n```\r\n\r\nThis way we create pseudo-data mapper, which adapts our API according to the SPA requirements.\r\n\r\nWe can use the `User` service by:\r\n\r\n```javascript\r\nfunction MainCtrl($scope, User) {\r\n User.get({ id: 1 })\r\n .then(function (data) {\r\n $scope.user = data;\r\n });\r\n}\r\n```\r\n\r\nAnd the following partial:\r\n\r\n```html\r\n<div>\r\n <div>\r\n Name: {{user.name}}\r\n </div>\r\n <div>\r\n Address: {{user.address}}\r\n </div>\r\n <div>\r\n Friends with ids:\r\n <ul>\r\n <li ng-repeat=\"friend in user.friends\">{{friend}}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n```\r\n\r\n### Observer Pattern as an External Service\r\n\r\n##### About\r\n\r\nBelow is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.\r\n\r\n**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.\r\n\r\n##### Controller Example\r\n\r\nBelow example shows how to attach, notify and detach an event.\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout) {\r\n var vm = this;\r\n var id = 'vm1';\r\n\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n ObserverService.detachByEvent('let_me_know')\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n}\r\n```\r\nAlternative way to remove event\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout', '$scope'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout, $scope) {\r\n var vm = this;\r\n var id = 'vm1';\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n\r\n // Cleanup listeners when this controller is destroyed\r\n $scope.$on('$destroy', function handler() {\r\n ObserverService.detachByEvent('let_me_know')\r\n });\r\n}\r\n```\r\n\r\n## References\r\n\r\n1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.\r\n2. [AngularJS' documentation](https://docs.angularjs.org)\r\n3. [AngularJS' git repository](https://github.com/angular/angular.js)\r\n4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx)\r\n5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html)\r\n6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html)\r\n7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery)\r\n","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"AngularJS in Patterns","tagline":"\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.","body":"# AngularJS in Patterns\r\n\r\n<!--toc-->\r\n\r\n## Table of Contents\r\n\r\n* [Translations](#translations)\r\n* [Abstract](#abstract)\r\n* [Introduction](#introduction)\r\n* [AngularJS overview](#angularjs-overview)\r\n * [Partials](#partials)\r\n * [Controllers](#controllers)\r\n * [Scope](#scope)\r\n * [Directives](#directives)\r\n * [Filters](#filters)\r\n * [Services](#services)\r\n* [AngularJS Patterns](#angularjs-patterns)\r\n * [Services](#services-1)\r\n * [Singleton](#singleton)\r\n * [Factory Method](#factory-method)\r\n * [Decorator](#decorator)\r\n * [Facade](#facade)\r\n * [Proxy](#proxy)\r\n * [Active Record](#active-record)\r\n * [Intercepting Filters](#intercepting-filters)\r\n * [Directives](#directives-1)\r\n * [Composite](#composite)\r\n * [Interpreter](#interpreter)\r\n * [Template View](#template-view)\r\n * [Scope](#scope-1)\r\n * [Observer](#observer)\r\n * [Chain of Responsibilities](#chain-of-responsibilities)\r\n * [Command](#command)\r\n * [Controller](#controller-1)\r\n * [Page Controller](#page-controller)\r\n * [Others](#others)\r\n * [Module Pattern](#module-pattern)\r\n * [Data Mapper](#data-mapper)\r\n * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n* [References](#references)\r\n\r\n<!--endtoc-->\r\n\r\n## Translations\r\n\r\n- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter)\r\n- [Russian Translation](http://habrahabr.ru/post/250149/)\r\n- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko)\r\n\r\n## Abstract\r\n\r\nOne of the best ways to learn something new is to see how the things you already know are used in it.\r\nThis document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns.\r\nThe goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.\r\n\r\n## Introduction\r\n\r\nThe document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.\r\n\r\nThe last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.\r\n\r\n## AngularJS overview\r\n\r\nAngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA).\r\nSPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand.\r\nSince most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:\r\n\r\n- two-way data binding\r\n- dependency injection\r\n- separation of concerns\r\n- testability\r\n- abstraction\r\n\r\nThe separation of concerns is achieved by dividing each AngularJS application into separate components, such as:\r\n\r\n- partials\r\n- controllers\r\n- directives\r\n- services\r\n- filters\r\n\r\nThese components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.\r\n\r\n### Partials\r\n\r\nThe partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).\r\n\r\nInitially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.\r\n\r\n**Sample partial**\r\n\r\n```HTML\r\n<html ng-app>\r\n <!-- Body tag augmented with ngController directive -->\r\n <body ng-controller=\"MyController\">\r\n <input ng-model=\"foo\" value=\"bar\">\r\n <!-- Button tag with ng-click directive, and\r\n string expression 'buttonText'\r\n wrapped in \"{{ }}\" markup -->\r\n <button ng-click=\"changeFoo()\">{{buttonText}}</button>\r\n <script src=\"angular.js\"></script>\r\n </body>\r\n</html>\r\n```\r\n\r\nWith AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked.\r\n\r\n### Controllers\r\n\r\nThe AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*.\r\n\r\n```JavaScript\r\nfunction MyController($scope) {\r\n $scope.buttonText = 'Click me to change foo!';\r\n $scope.foo = 42;\r\n\r\n $scope.changeFoo = function () {\r\n $scope.foo += 1;\r\n alert('Foo changed');\r\n };\r\n}\r\n```\r\n\r\nFor example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.\r\n\r\n1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding.\r\n2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`.\r\n\r\nAll the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones.\r\n\r\n### Scope\r\n\r\nIn AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.\r\n\r\nAnother important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.\r\n\r\nScope inheritance is illustrated in the following example:\r\n\r\n```HTML\r\n<div ng-controller=\"BaseCtrl\">\r\n <div id=\"child\" ng-controller=\"ChildCtrl\">\r\n <button id=\"parent-method\" ng-click=\"foo()\">Parent method</button>\r\n <button ng-click=\"bar()\">Child method</button>\r\n </div>\r\n</div>\r\n```\r\n\r\n```JavaScript\r\nfunction BaseCtrl($scope) {\r\n $scope.foo = function () {\r\n alert('Base foo');\r\n };\r\n}\r\n\r\nfunction ChildCtrl($scope) {\r\n $scope.bar = function () {\r\n alert('Child bar');\r\n };\r\n}\r\n```\r\n\r\nWith `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`.\r\n\r\n### Directives\r\n\r\nIn AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations.\r\nEach directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:\r\n\r\n- template\r\n- compile function\r\n- link function\r\n- etc...\r\n\r\nBy citing the name of the directives they can be used inside the declarative partials.\r\n\r\nExample:\r\n\r\n```JavaScript\r\nmyModule.directive('alertButton', function () {\r\n return {\r\n template: '<button ng-transclude></button>',\r\n scope: {\r\n content: '@'\r\n },\r\n replace: true,\r\n restrict: 'E',\r\n transclude: true,\r\n link: function (scope, el) {\r\n el.click(function () {\r\n alert(scope.content);\r\n });\r\n }\r\n };\r\n});\r\n```\r\n\r\n```HTML\r\n<alert-button content=\"42\">Click me</alert-button>\r\n```\r\n\r\nIn the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted.\r\n\r\nSince the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.\r\n\r\n### Filters\r\n\r\nThe filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection.\r\n\r\nHere is a definition of a sample filter, which changes the given string to uppercase:\r\n\r\n```JavaScript\r\nmyModule.filter('uppercase', function () {\r\n return function (str) {\r\n return (str || '').toUpperCase();\r\n };\r\n});\r\n```\r\n\r\nInside a partial this filter could be used using the Unix's piping syntax:\r\n\r\n```HTML\r\n<div>{{ name | uppercase }}</div>\r\n```\r\n\r\nInside a controller the filter could be used as follows:\r\n\r\n```JavaScript\r\nfunction MyCtrl(uppercaseFilter) {\r\n $scope.name = uppercaseFilter('foo'); //FOO\r\n}\r\n```\r\n\r\n### Services\r\n\r\nEvery piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too \"fat\" the repetitive code should be placed inside a service.\r\n\r\n```JavaScript\r\nmyModule.service('Developer', function () {\r\n this.name = 'Foo';\r\n this.motherLanguage = 'JavaScript';\r\n this.live = function () {\r\n while (true) {\r\n this.code();\r\n }\r\n };\r\n});\r\n```\r\n\r\nThe service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).\r\n\r\n```JavaScript\r\nfunction MyCtrl(Developer) {\r\n var developer = new Developer();\r\n developer.live();\r\n}\r\n```\r\n\r\n## AngularJS Patterns\r\n\r\nIn the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.\r\n\r\nIn the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.\r\n\r\n### Services\r\n\r\n#### Singleton\r\n\r\n>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.\r\n\r\nIn the UML diagram bellow is illustrated the singleton design pattern.\r\n\r\n\r\n\r\nWhen given dependency is required by any component, AngularJS resolves it using the following algorithm:\r\n\r\n- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).\r\n- If the dependency exists AngularJS pass it as parameter to the component, which requires it.\r\n- If the dependency does not exists:\r\n - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.\r\n - AngularJS caches it inside the hash map mentioned above.\r\n - AngularJS passes it as parameter to the component, which requires it.\r\n\r\nWe can take better look at the AngularJS' source code, which implements the method `getService`:\r\n\r\n```JavaScript\r\nfunction getService(serviceName) {\r\n if (cache.hasOwnProperty(serviceName)) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));\r\n }\r\n return cache[serviceName];\r\n } else {\r\n try {\r\n path.unshift(serviceName);\r\n cache[serviceName] = INSTANTIATING;\r\n return cache[serviceName] = factory(serviceName);\r\n } catch (err) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n delete cache[serviceName];\r\n }\r\n throw err;\r\n } finally {\r\n path.shift();\r\n }\r\n }\r\n}\r\n```\r\n\r\nWe can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`).\r\n\r\nThis way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:\r\n\r\n- It improves the testability of your source code\r\n- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)\r\n\r\nFor further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered.\r\n\r\n#### Factory Method\r\n\r\n>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.\r\n\r\n\r\n\r\nLets consider the following snippet:\r\n\r\n```JavaScript\r\nmyModule.config(function ($provide) {\r\n $provide.provider('foo', function () {\r\n var baz = 42;\r\n return {\r\n //Factory method\r\n $get: function (bar) {\r\n var baz = bar.baz();\r\n return {\r\n baz: baz\r\n };\r\n }\r\n };\r\n });\r\n});\r\n\r\n```\r\n\r\nIn the code above we use the `config` callback in order to define new \"provider\". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.\r\n\r\nEach service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.\r\n\r\nWe can dig a little bit deeper in AngularJS' implementation:\r\n\r\n```JavaScript\r\n//...\r\n\r\ncreateInternalInjector(instanceCache, function(servicename) {\r\n var provider = providerInjector.get(servicename + providerSuffix);\r\n return instanceInjector.invoke(provider.$get, provider, undefined, servicename);\r\n}, strictDi));\r\n\r\n//...\r\n\r\nfunction invoke(fn, self, locals, serviceName){\r\n if (typeof locals === 'string') {\r\n serviceName = locals;\r\n locals = null;\r\n }\r\n\r\n var args = [],\r\n $inject = annotate(fn, strictDi, serviceName),\r\n length, i,\r\n key;\r\n\r\n for(i = 0, length = $inject.length; i < length; i++) {\r\n key = $inject[i];\r\n if (typeof key !== 'string') {\r\n throw $injectorMinErr('itkn',\r\n 'Incorrect injection token! Expected service name as string, got {0}', key);\r\n }\r\n args.push(\r\n locals && locals.hasOwnProperty(key)\r\n ? locals[key]\r\n : getService(key)\r\n );\r\n }\r\n if (!fn.$inject) {\r\n // this means that we must be an array.\r\n fn = fn[length];\r\n }\r\n\r\n return fn.apply(self, args);\r\n}\r\n```\r\n\r\nFrom the example above we can notice how the `$get` method is actually used:\r\n\r\n```JavaScript\r\ninstanceInjector.invoke(provider.$get, provider, undefined, servicename)\r\n```\r\n\r\nThe snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.\r\n\r\nIf we think in terms of the UML diagram above we can call the provider a \"ConcreteCreator\" and the actual component, which is being created a \"Product\".\r\n\r\nThere are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:\r\n\r\n- The most appropriate moment, when the component needs to be instantiated\r\n- Resolving all the dependencies required by the component\r\n- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)\r\n\r\n#### Decorator\r\n\r\n>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.\r\n\r\n\r\n\r\nAngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create \"wrapper\" of any service you have previously defined or used by a third-party:\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function (foo) {\r\n foo.bar();\r\n});\r\n\r\nmyModule.factory('foo', function () {\r\n return {\r\n bar: function () {\r\n console.log('I\\'m bar');\r\n },\r\n baz: function () {\r\n console.log('I\\'m baz');\r\n }\r\n };\r\n});\r\n\r\nmyModule.config(function ($provide) {\r\n $provide.decorator('foo', function ($delegate) {\r\n var barBackup = $delegate.bar;\r\n $delegate.bar = function () {\r\n console.log('Decorated');\r\n barBackup.apply($delegate, arguments);\r\n };\r\n return $delegate;\r\n });\r\n});\r\n```\r\nThe example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `\"foo\"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.\r\nWe decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.\r\n\r\nUsing this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop).\r\n\r\n#### Facade\r\n\r\n>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:\r\n\r\n>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;\r\n\r\n>2. make the library more readable, for the same reason;\r\n\r\n>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;\r\n\r\n>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).\r\n\r\n\r\n\r\nThere are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.\r\n\r\nFor example, lets take a look how we can create an `XMLHttpRequest` POST request:\r\n\r\n```JavaScript\r\nvar http = new XMLHttpRequest(),\r\n url = '/example/new',\r\n params = encodeURIComponent(data);\r\nhttp.open(\"POST\", url, true);\r\n\r\nhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\r\nhttp.setRequestHeader(\"Content-length\", params.length);\r\nhttp.setRequestHeader(\"Connection\", \"close\");\r\n\r\nhttp.onreadystatechange = function () {\r\n if(http.readyState == 4 && http.status == 200) {\r\n alert(http.responseText);\r\n }\r\n}\r\nhttp.send(params);\r\n```\r\nBut if we want to post this data using the AngularJS' `$http` service we can:\r\n\r\n```JavaScript\r\n$http({\r\n method: 'POST',\r\n url: '/example/new',\r\n data: data\r\n})\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nor we can even:\r\n\r\n```JavaScript\r\n$http.post('/someUrl', data)\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nThe second option provides pre-configured version, which creates a HTTP POST request to the given URL.\r\n\r\nEven higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections.\r\n\r\n#### Proxy\r\n\r\n>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.\r\n\r\n\r\n\r\nWe can distinguish three different types of proxy:\r\n\r\n- Virtual Proxy\r\n- Remote Proxy\r\n- Protection Proxy\r\n\r\nIn this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.\r\n\r\nIn the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = User.get({ id: 42 });\r\nconsole.log(user); //{}\r\n```\r\n\r\n`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.\r\n\r\nHow does this works with AngularJS? Well, lets consider the following snippet:\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $resource) {\r\n var User = $resource('/users/:id'),\r\n $scope.user = User.get({ id: 42 });\r\n}\r\n```\r\n\r\n```html\r\n<span ng-bind=\"user.name\"></span>\r\n```\r\nInitially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view.\r\n\r\n#### Active Record\r\n\r\n>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.\r\n\r\n\r\n\r\nAngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.\r\n\r\nAccording to the AngularJS' documentation `$resource` is:\r\n\r\n>A factory which creates a resource object that lets you interact with RESTful server-side data sources.\r\n>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.\r\n\r\nHere is how `$resource` could be used:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = new User({\r\n name: 'foo',\r\n age : 42\r\n });\r\n\r\nuser.$save();\r\n```\r\n\r\nThe call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.\r\n\r\nThis way we can use the constructor function and its static methods by:\r\n\r\n```JavaScript\r\nUser.get({ userid: userid });\r\n```\r\n\r\nThe code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)).\r\n\r\nYou can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource).\r\n\r\nSince Martin Fowler states that\r\n\r\n> responsibility of the Active Record object is to take care of the communication with the databse in order to create...\r\n\r\n`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as \"Active Record like RESTful communication\".\r\n\r\n#### Intercepting Filters\r\n\r\n>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.\r\n\r\n\r\n\r\nIn some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.\r\n\r\nIn AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`.\r\n\r\n`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error.\r\n\r\nHere is a basic example how you can add interceptors using object literal:\r\n\r\n```JavaScript\r\n$httpProvider.interceptors.push(function($q, dependency1, dependency2) {\r\n return {\r\n 'request': function(config) {\r\n // same as above\r\n },\r\n 'response': function(response) {\r\n // same as above\r\n }\r\n };\r\n});\r\n```\r\n\r\n### Directives\r\n\r\n#### Composite\r\n\r\n>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to \"compose\" objects into tree structures to represent part-whole hierarchies.\r\n\r\n\r\n\r\nAccording to the Gang of Four, MVC is nothing more than combination of:\r\n\r\n- Strategy\r\n- Composite\r\n- Observer\r\n\r\nThey state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.\r\n\r\nLets look at the following example:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body>\r\n <zippy title=\"Zippy\">\r\n Zippy!\r\n </zippy>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nmyModule.directive('zippy', function () {\r\n return {\r\n restrict: 'E',\r\n template: '<div><div class=\"header\"></div><div class=\"content\" ng-transclude></div></div>',\r\n link: function (scope, el) {\r\n el.find('.header').click(function () {\r\n el.find('.content').toggle();\r\n });\r\n }\r\n }\r\n});\r\n```\r\n\r\nThis example defines a simple directive, which is a UI component. The defined component (called \"zippy\") has header and content. Click on its header toggles the visibility of the content.\r\n\r\nFrom the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on...\r\n\r\nIn the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.\r\n\r\n### Interpreter\r\n\r\n>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.\r\n\r\n\r\n\r\nBehind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript.\r\nThe main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:\r\n\r\n- may contain filters with UNIX like pipe syntax\r\n- don't throw any errors\r\n- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)\r\n- are evaluated in given context (the context of the current `$scope`)\r\n\r\nInside the `$parse` service are defined two main components:\r\n\r\n```JavaScript\r\n//Responsible for converting given string into tokens\r\nvar Lexer;\r\n//Responsible for parsing the tokens and evaluating the expression\r\nvar Parser;\r\n```\r\n\r\nOnce given expression have been tokenized it is cached internally, because of performance concerns.\r\n\r\nThe terminal expressions in the AngularJS DSL are defined as follows:\r\n\r\n```JavaScript\r\nvar OPERATORS = {\r\n /* jshint bitwise : false */\r\n 'null':function(){return null;},\r\n 'true':function(){return true;},\r\n 'false':function(){return false;},\r\n undefined:noop,\r\n '+':function(self, locals, a,b){\r\n //...\r\n },\r\n '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},\r\n '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},\r\n '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},\r\n '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},\r\n '=':noop,\r\n '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},\r\n '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},\r\n '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},\r\n '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},\r\n '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},\r\n '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},\r\n '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},\r\n '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},\r\n '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},\r\n '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},\r\n '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},\r\n '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},\r\n '!':function(self, locals, a){return !a(self, locals);}\r\n};\r\n```\r\n\r\nWe can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface.\r\n\r\nEach `Client` interprets given AngularJS expression in a specific context - specific scope.\r\n\r\nFew sample AngularJS expressions are:\r\n\r\n```JavaScript\r\n// toUpperCase filter is applied to the result of the expression\r\n// (foo) ? bar : baz\r\n(foo) ? bar : baz | toUpperCase\r\n```\r\n\r\n#### Template View\r\n\r\n> Renders information into HTML by embedding markers in an HTML page.\r\n\r\n\r\n\r\nThe dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.\r\n\r\nTemplates are very commonly used especially in the back-end.\r\nFor example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.\r\n\r\nFor JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript.\r\n\r\nFor example:\r\n\r\n```html\r\n<script type=\"template/mustache\">\r\n <h2>Names</h2>\r\n {{#names}}\r\n <strong>{{name}}</strong>\r\n {{/names}}\r\n</script>\r\n```\r\n\r\nThe template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.\r\n\r\nFor example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get:\r\n\r\n```html\r\n<h2>Names</h2>\r\n <strong>foo</strong>\r\n <strong>bar</strong>\r\n <strong>baz</strong>\r\n```\r\n\r\nAngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are.\r\nWhat AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.\r\n\r\nFor example:\r\n\r\n```html\r\n<ul ng-repeat=\"name in names\">\r\n <li>{{name}}</li>\r\n</ul>\r\n```\r\n\r\nin the context of the scope:\r\n\r\n```javascript\r\n$scope.names = ['foo', 'bar', 'baz'];\r\n```\r\n\r\nwill produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead.\r\n\r\n\r\n### Scope\r\n\r\n#### Observer\r\n\r\n>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.\r\n\r\n\r\n\r\nThere are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.\r\n\r\nEach AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$on('event-name', function handler() {\r\n //body\r\n });\r\n}\r\n```\r\n\r\nIn this way the current scope \"subscribes\" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.\r\n\r\nThe methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.\r\nFor example:\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$emit('event-name', { foo: 'bar' });\r\n}\r\n```\r\n\r\nThe scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.\r\n\r\nAnalogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.\r\nEach scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).\r\n\r\nIn the JavaScript community this pattern is better known as publish/subscribe.\r\n\r\nFor a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n\r\n#### Chain of Responsibilities\r\n\r\n>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.\r\n\r\n\r\n\r\nAs stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are \"isolated\", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.\r\n\r\nWhen `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:\r\n\r\n- Handle the event and pass it to the next scope in the chain\r\n- Handle the event and stop its propagation\r\n- Pass the event to the next scope in the chain without handling it\r\n- Stop the event propagation without handling it\r\n\r\nIn the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `\"foo received\"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback.\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function ($scope) {\r\n $scope.$on('foo', function () {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ParentCtrl', function ($scope) {\r\n $scope.$on('foo', function (e) {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ChildCtrl', function ($scope) {\r\n $scope.$emit('foo');\r\n});\r\n```\r\n\r\nThe different handlers from the UML diagram above are the different scopes, injected to the controllers.\r\n\r\n#### Command\r\n\r\n>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.\r\n\r\n\r\n\r\nBefore continuing with the application of the command pattern lets describe how AngularJS implements data binding.\r\n\r\nWhen we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can:\r\n\r\n```html\r\n<span ng-bind=\"foo\"></span>\r\n```\r\n\r\nNow each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:\r\n\r\n```html\r\n<span ng-bind=\"foo + ' ' + bar | uppercase\"></span>\r\n```\r\n\r\nIn the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene?\r\n\r\nEach `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch(\"foo + ' ' + bar | uppercase\", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.\r\n\r\nHere are the first a couple of lines of the implementation of `$watch`:\r\n\r\n```javascript\r\n$watch: function(watchExp, listener, objectEquality) {\r\n var scope = this,\r\n get = compileToFn(watchExp, 'watch'),\r\n array = scope.$$watchers,\r\n watcher = {\r\n fn: listener,\r\n last: initWatchVal,\r\n get: get,\r\n exp: watchExp,\r\n eq: !!objectEquality\r\n };\r\n//...\r\n```\r\n\r\nWe can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`\"$digest\"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`.\r\n\r\n### Controllers\r\n\r\n#### Page Controller\r\n\r\n>An object that handles a request for a specific page or action on a Web site. Martin Fowler\r\n\r\n\r\n\r\nAccording to [4](#references) the page controller:\r\n\r\n>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code\r\n\r\nSince there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.\r\n\r\nSimilarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.\r\n\r\nThe controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.\r\nHere is an example hierarchy between few controllers:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body ng-controller=\"MainCtrl\">\r\n <div ng-controller=\"ChildCtrl\">\r\n <span>{{user.name}}</span>\r\n <button ng-click=\"click()\">Click</button>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $location, User) {\r\n if (!User.isAuthenticated()) {\r\n $location.path('/unauthenticated');\r\n }\r\n}\r\n\r\nfunction ChildCtrl($scope, User) {\r\n $scope.click = function () {\r\n alert('You clicked me!');\r\n };\r\n $scope.user = User.get(0);\r\n}\r\n```\r\n\r\nThis example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.\r\n\r\nThe `ChildCtrl` is responsible for handling actions such as clicking the button with label `\"Click\"` and exposing the model to the view, by attaching it to the scope.\r\n\r\n### Others\r\n\r\n#### Module Pattern\r\n\r\nThis is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.\r\n\r\nUsing the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:\r\n\r\n```javascript\r\nvar Page = (function () {\r\n\r\n var title;\r\n\r\n function setTitle(t) {\r\n document.title = t;\r\n title = t;\r\n }\r\n\r\n function getTitle() {\r\n return title;\r\n }\r\n\r\n return {\r\n setTitle: setTitle,\r\n getTitle: getTitle\r\n };\r\n}());\r\n```\r\n\r\nIn the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.\r\n\r\nIn this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE.\r\n\r\nThe module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:\r\n\r\n```javascript\r\napp.factory('foo', function () {\r\n\r\n function privateMember() {\r\n //body...\r\n }\r\n\r\n function publicMember() {\r\n //body...\r\n privateMember();\r\n //body\r\n }\r\n\r\n return {\r\n publicMember: publicMember\r\n };\r\n});\r\n```\r\n\r\nOnce we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.\r\n\r\n### Data Mapper\r\n\r\n>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.\r\n\r\n\r\n\r\nAs the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).\r\n\r\nUsually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.\r\n\r\nFor instance, lets assume we have application in which each user has:\r\n\r\n- name\r\n- address\r\n- list of friends\r\n\r\nAnd our API has the methods:\r\n\r\n- `GET /user/:id` - returns the user's name and the address of given user\r\n- `GET /friends/:id` - returns the list of friends of given user\r\n\r\nPossible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:\r\n\r\n```javascript\r\napp.factory('User', function ($q) {\r\n\r\n function User(name, address, friends) {\r\n this.name = name;\r\n this.address = address;\r\n this.friends = friends;\r\n }\r\n\r\n User.get = function (params) {\r\n var user = $http.get('/user/' + params.id),\r\n friends = $http.get('/friends/' + params.id);\r\n $q.all([user, friends])\r\n .then(function (user, friends) {\r\n return new User(user.name, user.address, friends);\r\n });\r\n };\r\n return User;\r\n});\r\n```\r\n\r\nThis way we create pseudo-data mapper, which adapts our API according to the SPA requirements.\r\n\r\nWe can use the `User` service by:\r\n\r\n```javascript\r\nfunction MainCtrl($scope, User) {\r\n User.get({ id: 1 })\r\n .then(function (data) {\r\n $scope.user = data;\r\n });\r\n}\r\n```\r\n\r\nAnd the following partial:\r\n\r\n```html\r\n<div>\r\n <div>\r\n Name: {{user.name}}\r\n </div>\r\n <div>\r\n Address: {{user.address}}\r\n </div>\r\n <div>\r\n Friends with ids:\r\n <ul>\r\n <li ng-repeat=\"friend in user.friends\">{{friend}}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n```\r\n\r\n### Observer Pattern as an External Service\r\n\r\n##### About\r\n\r\nBelow is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.\r\n\r\n**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.\r\n\r\n##### Controller Example\r\n\r\nBelow example shows how to attach, notify and detach an event.\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout) {\r\n var vm = this;\r\n var id = 'vm1';\r\n\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n ObserverService.detachByEvent('let_me_know')\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n}\r\n```\r\nAlternative way to remove event\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout', '$scope'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout, $scope) {\r\n var vm = this;\r\n var id = 'vm1';\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n\r\n // Cleanup listeners when this controller is destroyed\r\n $scope.$on('$destroy', function handler() {\r\n ObserverService.detachByEvent('let_me_know')\r\n });\r\n}\r\n```\r\n\r\n## References\r\n\r\n1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.\r\n2. [AngularJS' documentation](https://docs.angularjs.org)\r\n3. [AngularJS' git repository](https://github.com/angular/angular.js)\r\n4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx)\r\n5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html)\r\n6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html)\r\n7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery)\r\n","google":"UA-18060688-20","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 413e76a16c1c6647441b97fc1f0dcc871fc730df Mon Sep 17 00:00:00 2001 From: Minko Gechev <mgechev@gmail.com> Date: Thu, 17 Sep 2015 15:50:27 +0300 Subject: [PATCH 15/19] Create gh-pages branch via GitHub --- index.html | 285 ++++++++++++++++++++++++++-------------------------- params.json | 2 +- 2 files changed, 141 insertions(+), 146 deletions(-) diff --git a/index.html b/index.html index 7060d8d..848aaa4 100644 --- a/index.html +++ b/index.html @@ -65,12 +65,7 @@ <h2> <ul> <li><a href="#composite">Composite</a></li> -</ul> -</li> -<li> -<a href="#interpreter">Interpreter</a> - -<ul> +<li><a href="#interpreter">Interpreter</a></li> <li><a href="#template-view">Template View</a></li> </ul> </li> @@ -169,7 +164,7 @@ <h3> <p><strong>Sample partial</strong></p> -<div class="highlight highlight-HTML"><pre><<span class="pl-ent">html</span> <span class="pl-e">ng-app</span>> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">html</span> <span class="pl-e">ng-app</span>> <span class="pl-c"><!-- Body tag augmented with ngController directive --></span> <<span class="pl-ent">body</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>MyController<span class="pl-pds">"</span></span>> <<span class="pl-ent">input</span> <span class="pl-e">ng-model</span>=<span class="pl-s"><span class="pl-pds">"</span>foo<span class="pl-pds">"</span></span> <span class="pl-e">value</span>=<span class="pl-s"><span class="pl-pds">"</span>bar<span class="pl-pds">"</span></span>> @@ -188,12 +183,12 @@ <h3> <p>The AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the <em>scope</em>. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the <em>model</em> to the partials by attaching data to the <em>scope</em>. We can think of this data as <em>view model</em>.</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MyController</span>(<span class="pl-smi">$scope</span>) { - $scope.<span class="pl-c1">buttonText</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Click me to change foo!<span class="pl-pds">'</span></span>; - $scope.<span class="pl-c1">foo</span> <span class="pl-k">=</span> <span class="pl-c1">42</span>; +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MyController</span>(<span class="pl-smi">$scope</span>) { + $scope.buttonText <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Click me to change foo!<span class="pl-pds">'</span></span>; + $scope.foo <span class="pl-k">=</span> <span class="pl-c1">42</span>; <span class="pl-c1">$scope</span>.<span class="pl-en">changeFoo</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - $scope.<span class="pl-c1">foo</span> <span class="pl-k">+=</span> <span class="pl-c1">1</span>; + $scope.foo <span class="pl-k">+=</span> <span class="pl-c1">1</span>; <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>Foo changed<span class="pl-pds">'</span></span>); }; }</pre></div> @@ -216,14 +211,14 @@ <h3> <p>Scope inheritance is illustrated in the following example:</p> -<div class="highlight highlight-HTML"><pre><<span class="pl-ent">div</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>BaseCtrl<span class="pl-pds">"</span></span>> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">div</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>BaseCtrl<span class="pl-pds">"</span></span>> <<span class="pl-ent">div</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>child<span class="pl-pds">"</span></span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>ChildCtrl<span class="pl-pds">"</span></span>> <<span class="pl-ent">button</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>parent-method<span class="pl-pds">"</span></span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>foo()<span class="pl-pds">"</span></span>>Parent method</<span class="pl-ent">button</span>> <<span class="pl-ent">button</span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>bar()<span class="pl-pds">"</span></span>>Child method</<span class="pl-ent">button</span>> </<span class="pl-ent">div</span>> </<span class="pl-ent">div</span>></pre></div> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">BaseCtrl</span>(<span class="pl-smi">$scope</span>) { +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">BaseCtrl</span>(<span class="pl-smi">$scope</span>) { <span class="pl-c1">$scope</span>.<span class="pl-en">foo</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>Base foo<span class="pl-pds">'</span></span>); }; @@ -254,7 +249,7 @@ <h3> <p>Example:</p> -<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">directive</span>(<span class="pl-s"><span class="pl-pds">'</span>alertButton<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { +<div class="highlight highlight-source-js"><pre>myModule.directive(<span class="pl-s"><span class="pl-pds">'</span>alertButton<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-k">return</span> { template<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span><button ng-transclude></button><span class="pl-pds">'</span></span>, scope<span class="pl-k">:</span> { @@ -271,7 +266,7 @@ <h3> }; });</pre></div> -<div class="highlight highlight-HTML"><pre><<span class="pl-ent">alert</span><span class="pl-e">-button</span> <span class="pl-e">content</span>=<span class="pl-s"><span class="pl-pds">"</span>42<span class="pl-pds">"</span></span>>Click me</<span class="pl-ent">alert</span><span class="pl-e">-button</span>></pre></div> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">alert</span><span class="pl-e">-button</span> <span class="pl-e">content</span>=<span class="pl-s"><span class="pl-pds">"</span>42<span class="pl-pds">"</span></span>>Click me</<span class="pl-ent">alert</span><span class="pl-e">-button</span>></pre></div> <p>In the example above the tag <code><alert-button></alert-button></code> will be replaced button element. When the user clicks on the button the string <code>42</code> will be alerted.</p> @@ -284,7 +279,7 @@ <h3> <p>Here is a definition of a sample filter, which changes the given string to uppercase:</p> -<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">filter</span>(<span class="pl-s"><span class="pl-pds">'</span>uppercase<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { +<div class="highlight highlight-source-js"><pre>myModule.filter(<span class="pl-s"><span class="pl-pds">'</span>uppercase<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-k">return</span> <span class="pl-k">function</span> (<span class="pl-smi">str</span>) { <span class="pl-k">return</span> (str <span class="pl-k">||</span> <span class="pl-s"><span class="pl-pds">'</span><span class="pl-pds">'</span></span>).<span class="pl-c1">toUpperCase</span>(); }; @@ -292,12 +287,12 @@ <h3> <p>Inside a partial this filter could be used using the Unix's piping syntax:</p> -<div class="highlight highlight-HTML"><pre><<span class="pl-ent">div</span>>{{ name | uppercase }}</<span class="pl-ent">div</span>></pre></div> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">div</span>>{{ name | uppercase }}</<span class="pl-ent">div</span>></pre></div> <p>Inside a controller the filter could be used as follows:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MyCtrl</span>(<span class="pl-smi">uppercaseFilter</span>) { - $scope.<span class="pl-c1">name</span> <span class="pl-k">=</span> <span class="pl-c1">uppercaseFilter</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>); <span class="pl-c">//FOO</span> +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MyCtrl</span>(<span class="pl-smi">uppercaseFilter</span>) { + $scope.<span class="pl-c1">name</span> <span class="pl-k">=</span> uppercaseFilter(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>); <span class="pl-c">//FOO</span> }</pre></div> <h3> @@ -305,9 +300,9 @@ <h3> <p>Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service.</p> -<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">service</span>(<span class="pl-s"><span class="pl-pds">'</span>Developer<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { +<div class="highlight highlight-source-js"><pre>myModule.service(<span class="pl-s"><span class="pl-pds">'</span>Developer<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-v">this</span>.<span class="pl-c1">name</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Foo<span class="pl-pds">'</span></span>; - <span class="pl-v">this</span>.<span class="pl-c1">motherLanguage</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>JavaScript<span class="pl-pds">'</span></span>; + <span class="pl-v">this</span>.motherLanguage <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>JavaScript<span class="pl-pds">'</span></span>; <span class="pl-c1">this</span>.<span class="pl-en">live</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { <span class="pl-k">while</span> (<span class="pl-c1">true</span>) { <span class="pl-v">this</span>.<span class="pl-c1">code</span>(); @@ -317,9 +312,9 @@ <h3> <p>The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MyCtrl</span>(<span class="pl-smi">Developer</span>) { +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MyCtrl</span>(<span class="pl-smi">Developer</span>) { <span class="pl-k">var</span> developer <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Developer</span>(); - developer.<span class="pl-c1">live</span>(); + developer.live(); }</pre></div> <h2> @@ -360,17 +355,17 @@ <h4> <p>We can take better look at the AngularJS' source code, which implements the method <code>getService</code>:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">getService</span>(<span class="pl-smi">serviceName</span>) { - <span class="pl-k">if</span> (cache.<span class="pl-c1">hasOwnProperty</span>(serviceName)) { +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">getService</span>(<span class="pl-smi">serviceName</span>) { + <span class="pl-k">if</span> (cache.hasOwnProperty(serviceName)) { <span class="pl-k">if</span> (cache[serviceName] <span class="pl-k">===</span> <span class="pl-c1">INSTANTIATING</span>) { - <span class="pl-k">throw</span> $<span class="pl-c1">injectorMinErr</span>(<span class="pl-s"><span class="pl-pds">'</span>cdep<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>Circular dependency found: {0}<span class="pl-pds">'</span></span>, path.<span class="pl-c1">join</span>(<span class="pl-s"><span class="pl-pds">'</span> <- <span class="pl-pds">'</span></span>)); + <span class="pl-k">throw</span> $injectorMinErr(<span class="pl-s"><span class="pl-pds">'</span>cdep<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>Circular dependency found: {0}<span class="pl-pds">'</span></span>, path.<span class="pl-c1">join</span>(<span class="pl-s"><span class="pl-pds">'</span> <- <span class="pl-pds">'</span></span>)); } <span class="pl-k">return</span> cache[serviceName]; } <span class="pl-k">else</span> { <span class="pl-k">try</span> { path.<span class="pl-c1">unshift</span>(serviceName); cache[serviceName] <span class="pl-k">=</span> <span class="pl-c1">INSTANTIATING</span>; - <span class="pl-k">return</span> cache[serviceName] <span class="pl-k">=</span> <span class="pl-c1">factory</span>(serviceName); + <span class="pl-k">return</span> cache[serviceName] <span class="pl-k">=</span> factory(serviceName); } <span class="pl-k">catch</span> (err) { <span class="pl-k">if</span> (cache[serviceName] <span class="pl-k">===</span> <span class="pl-c1">INSTANTIATING</span>) { <span class="pl-k">delete</span> cache[serviceName]; @@ -404,13 +399,13 @@ <h4> <p>Lets consider the following snippet:</p> -<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">config</span>(<span class="pl-k">function</span> (<span class="pl-smi">$provide</span>) { - $provide.<span class="pl-c1">provider</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { +<div class="highlight highlight-source-js"><pre>myModule.config(<span class="pl-k">function</span> (<span class="pl-smi">$provide</span>) { + $provide.provider(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-k">var</span> baz <span class="pl-k">=</span> <span class="pl-c1">42</span>; <span class="pl-k">return</span> { <span class="pl-c">//Factory method</span> $<span class="pl-en">get</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span class="pl-smi">bar</span>) { - <span class="pl-k">var</span> baz <span class="pl-k">=</span> bar.<span class="pl-c1">baz</span>(); + <span class="pl-k">var</span> baz <span class="pl-k">=</span> bar.baz(); <span class="pl-k">return</span> { baz<span class="pl-k">:</span> baz }; @@ -426,11 +421,11 @@ <h4> <p>We can dig a little bit deeper in AngularJS' implementation:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-c">//...</span> +<div class="highlight highlight-source-js"><pre><span class="pl-c">//...</span> -<span class="pl-c1">createInternalInjector</span>(instanceCache, <span class="pl-k">function</span>(<span class="pl-smi">servicename</span>) { - <span class="pl-k">var</span> provider <span class="pl-k">=</span> providerInjector.<span class="pl-c1">get</span>(servicename <span class="pl-k">+</span> providerSuffix); - <span class="pl-k">return</span> instanceInjector.<span class="pl-c1">invoke</span>(provider.$get, provider, <span class="pl-c1">undefined</span>, servicename); +createInternalInjector(instanceCache, <span class="pl-k">function</span>(<span class="pl-smi">servicename</span>) { + <span class="pl-k">var</span> provider <span class="pl-k">=</span> providerInjector.get(servicename <span class="pl-k">+</span> providerSuffix); + <span class="pl-k">return</span> instanceInjector.invoke(provider.$get, provider, <span class="pl-c1">undefined</span>, servicename); }, strictDi)); <span class="pl-c">//...</span> @@ -442,20 +437,20 @@ <h4> } <span class="pl-k">var</span> args <span class="pl-k">=</span> [], - $inject <span class="pl-k">=</span> <span class="pl-c1">annotate</span>(fn, strictDi, serviceName), + $inject <span class="pl-k">=</span> annotate(fn, strictDi, serviceName), length, i, key; <span class="pl-k">for</span>(i <span class="pl-k">=</span> <span class="pl-c1">0</span>, length <span class="pl-k">=</span> $inject.<span class="pl-c1">length</span>; i <span class="pl-k"><</span> length; i<span class="pl-k">++</span>) { key <span class="pl-k">=</span> $inject[i]; <span class="pl-k">if</span> (<span class="pl-k">typeof</span> key <span class="pl-k">!==</span> <span class="pl-s"><span class="pl-pds">'</span>string<span class="pl-pds">'</span></span>) { - <span class="pl-k">throw</span> $<span class="pl-c1">injectorMinErr</span>(<span class="pl-s"><span class="pl-pds">'</span>itkn<span class="pl-pds">'</span></span>, + <span class="pl-k">throw</span> $injectorMinErr(<span class="pl-s"><span class="pl-pds">'</span>itkn<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>Incorrect injection token! Expected service name as string, got {0}<span class="pl-pds">'</span></span>, key); } args.<span class="pl-c1">push</span>( - locals <span class="pl-k">&&</span> locals.<span class="pl-c1">hasOwnProperty</span>(key) + locals <span class="pl-k">&&</span> locals.hasOwnProperty(key) <span class="pl-k">?</span> locals[key] - <span class="pl-k">:</span> <span class="pl-c1">getService</span>(key) + <span class="pl-k">:</span> getService(key) ); } <span class="pl-k">if</span> (<span class="pl-k">!</span>fn.$inject) { @@ -468,7 +463,7 @@ <h4> <p>From the example above we can notice how the <code>$get</code> method is actually used:</p> -<div class="highlight highlight-JavaScript"><pre>instanceInjector.<span class="pl-c1">invoke</span>(provider.$get, provider, <span class="pl-c1">undefined</span>, servicename)</pre></div> +<div class="highlight highlight-source-js"><pre>instanceInjector.invoke(provider.$get, provider, <span class="pl-c1">undefined</span>, servicename)</pre></div> <p>The snippet above calls the <code>invoke</code> method of <code>instanceInjector</code> with the factory method (i.e. <code>$get</code>) of given service, as first argument. Inside <code>invoke</code>'s body <code>annotate</code> is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: <code>fn.apply(self, args)</code>.</p> @@ -493,11 +488,11 @@ <h4> <p>AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method <code>decorator</code> of <code>$provide</code> you can create "wrapper" of any service you have previously defined or used by a third-party:</p> -<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">foo</span>) { - foo.<span class="pl-c1">bar</span>(); +<div class="highlight highlight-source-js"><pre>myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">foo</span>) { + foo.bar(); }); -myModule.<span class="pl-c1">factory</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { +myModule.factory(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-k">return</span> { <span class="pl-en">bar</span><span class="pl-k">:</span> <span class="pl-k">function</span> () { <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m bar<span class="pl-pds">'</span></span>); @@ -508,9 +503,9 @@ <h4> }; }); -myModule.<span class="pl-c1">config</span>(<span class="pl-k">function</span> (<span class="pl-smi">$provide</span>) { - $provide.<span class="pl-c1">decorator</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$delegate</span>) { - <span class="pl-k">var</span> barBackup <span class="pl-k">=</span> $delegate.<span class="pl-c1">bar</span>; +myModule.config(<span class="pl-k">function</span> (<span class="pl-smi">$provide</span>) { + $provide.decorator(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$delegate</span>) { + <span class="pl-k">var</span> barBackup <span class="pl-k">=</span> $delegate.bar; <span class="pl-c1">$delegate</span>.<span class="pl-en">bar</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>Decorated<span class="pl-pds">'</span></span>); barBackup.<span class="pl-c1">apply</span>($delegate, arguments); @@ -544,9 +539,9 @@ <h4> <p>For example, lets take a look how we can create an <code>XMLHttpRequest</code> POST request:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">var</span> http <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">XMLHttpRequest</span>(), +<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> http <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">XMLHttpRequest</span>(), url <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>/example/new<span class="pl-pds">'</span></span>, - params <span class="pl-k">=</span> <span class="pl-c1">encodeURIComponent</span>(data); + params <span class="pl-k">=</span> encodeURIComponent(data); http.<span class="pl-c1">open</span>(<span class="pl-s"><span class="pl-pds">"</span>POST<span class="pl-pds">"</span></span>, url, <span class="pl-c1">true</span>); http.<span class="pl-c1">setRequestHeader</span>(<span class="pl-s"><span class="pl-pds">"</span>Content-type<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>application/x-www-form-urlencoded<span class="pl-pds">"</span></span>); @@ -555,26 +550,26 @@ <h4> <span class="pl-c1">http</span>.<span class="pl-en">onreadystatechange</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { <span class="pl-k">if</span>(http.<span class="pl-c1">readyState</span> <span class="pl-k">==</span> <span class="pl-c1">4</span> <span class="pl-k">&&</span> http.<span class="pl-c1">status</span> <span class="pl-k">==</span> <span class="pl-c1">200</span>) { - <span class="pl-c1">alert</span>(http.<span class="pl-c1">responseText</span>); + <span class="pl-c1">alert</span>(http.responseText); } } http.<span class="pl-c1">send</span>(params);</pre></div> <p>But if we want to post this data using the AngularJS' <code>$http</code> service we can:</p> -<div class="highlight highlight-JavaScript"><pre>$<span class="pl-c1">http</span>({ +<div class="highlight highlight-source-js"><pre>$http({ method<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>POST<span class="pl-pds">'</span></span>, url<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>/example/new<span class="pl-pds">'</span></span>, data<span class="pl-k">:</span> data }) -.<span class="pl-c1">then</span>(<span class="pl-k">function</span> (<span class="pl-smi">response</span>) { +.then(<span class="pl-k">function</span> (<span class="pl-smi">response</span>) { <span class="pl-c1">alert</span>(response); });</pre></div> <p>or we can even:</p> -<div class="highlight highlight-JavaScript"><pre>$http.<span class="pl-c1">post</span>(<span class="pl-s"><span class="pl-pds">'</span>/someUrl<span class="pl-pds">'</span></span>, data) -.<span class="pl-c1">then</span>(<span class="pl-k">function</span> (<span class="pl-smi">response</span>) { +<div class="highlight highlight-source-js"><pre>$http.post(<span class="pl-s"><span class="pl-pds">'</span>/someUrl<span class="pl-pds">'</span></span>, data) +.then(<span class="pl-k">function</span> (<span class="pl-smi">response</span>) { <span class="pl-c1">alert</span>(response); });</pre></div> @@ -603,20 +598,20 @@ <h4> <p>In the snippet bellow, there is a call to the <code>get</code> method of <code>$resource</code> instance, called <code>User</code>:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $<span class="pl-c1">resource</span>(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), - user <span class="pl-k">=</span> User.<span class="pl-c1">get</span>({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); +<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $resource(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), + user <span class="pl-k">=</span> User.get({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); <span class="pl-en">console</span><span class="pl-c1">.log</span>(user); <span class="pl-c">//{}</span></pre></div> <p><code>console.log</code> would outputs an empty object. Since the AJAX request, which happens behind the scene, when <code>User.get</code> is invoked, is asynchronous, we don't have the actual user when <code>console.log</code> is called. Just after <code>User.get</code> makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.</p> <p>How does this works with AngularJS? Well, lets consider the following snippet:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">$resource</span>) { - <span class="pl-k">var</span> User <span class="pl-k">=</span> $<span class="pl-c1">resource</span>(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), - $scope.<span class="pl-c1">user</span> <span class="pl-k">=</span> User.<span class="pl-c1">get</span>({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">$resource</span>) { + <span class="pl-k">var</span> User <span class="pl-k">=</span> $resource(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), + $scope.user <span class="pl-k">=</span> User.get({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); }</pre></div> -<div class="highlight highlight-html"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>user.name<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>user.name<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> <p>Initially when the snippet above executes, the property <code>user</code> of the <code>$scope</code> object will be with value an empty object (<code>{}</code>), which means that <code>user.name</code> will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next <code>$digest</code> loop AngularJS will detect change in <code>$scope.user</code>, which will lead to update of the view.</p> @@ -640,19 +635,19 @@ <h4> <p>Here is how <code>$resource</code> could be used:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $<span class="pl-c1">resource</span>(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), +<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $resource(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), user <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">User</span>({ name<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, age <span class="pl-k">:</span> <span class="pl-c1">42</span> }); -user.$<span class="pl-c1">save</span>();</pre></div> +user.$save();</pre></div> <p>The call of <code>$resource</code> will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.</p> <p>This way we can use the constructor function and its static methods by:</p> -<div class="highlight highlight-JavaScript"><pre>User.<span class="pl-c1">get</span>({ userid<span class="pl-k">:</span> userid });</pre></div> +<div class="highlight highlight-source-js"><pre>User.get({ userid<span class="pl-k">:</span> userid });</pre></div> <p>The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see <a href="#proxy">proxy</a>).</p> @@ -683,7 +678,7 @@ <h4> <p>Here is a basic example how you can add interceptors using object literal:</p> -<div class="highlight highlight-JavaScript"><pre>$httpProvider.<span class="pl-c1">interceptors</span>.<span class="pl-c1">push</span>(<span class="pl-k">function</span>(<span class="pl-smi">$q</span>, <span class="pl-smi">dependency1</span>, <span class="pl-smi">dependency2</span>) { +<div class="highlight highlight-source-js"><pre>$httpProvider.interceptors.<span class="pl-c1">push</span>(<span class="pl-k">function</span>(<span class="pl-smi">$q</span>, <span class="pl-smi">dependency1</span>, <span class="pl-smi">dependency2</span>) { <span class="pl-k">return</span> { <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">request</span><span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">config</span>) { <span class="pl-c">// same as above</span> @@ -718,7 +713,7 @@ <h4> <p>Lets look at the following example:</p> -<div class="highlight highlight-HTML"><pre><!doctype html> +<div class="highlight highlight-text-html-basic"><pre><!doctype html> <<span class="pl-ent">html</span>> <<span class="pl-ent">head</span>> </<span class="pl-ent">head</span>> @@ -729,13 +724,13 @@ <h4> </<span class="pl-ent">body</span>> </<span class="pl-ent">html</span>></pre></div> -<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">directive</span>(<span class="pl-s"><span class="pl-pds">'</span>zippy<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { +<div class="highlight highlight-source-js"><pre>myModule.directive(<span class="pl-s"><span class="pl-pds">'</span>zippy<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-k">return</span> { restrict<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>E<span class="pl-pds">'</span></span>, template<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span><div><div class="header"></div><div class="content" ng-transclude></div></div><span class="pl-pds">'</span></span>, <span class="pl-en">link</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span class="pl-smi">scope</span>, <span class="pl-smi">el</span>) { el.<span class="pl-c1">find</span>(<span class="pl-s"><span class="pl-pds">'</span>.header<span class="pl-pds">'</span></span>).<span class="pl-c1">click</span>(<span class="pl-k">function</span> () { - el.<span class="pl-c1">find</span>(<span class="pl-s"><span class="pl-pds">'</span>.content<span class="pl-pds">'</span></span>).<span class="pl-c1">toggle</span>(); + el.<span class="pl-c1">find</span>(<span class="pl-s"><span class="pl-pds">'</span>.content<span class="pl-pds">'</span></span>).toggle(); }); } } @@ -747,8 +742,8 @@ <h4> <p>In the second, JavaScript, example we see that the <code>template</code> property of the directive, contains markup with <code>ng-transclude</code> directive inside it. So this means that inside the directive <code>zippy</code> we have another directive called <code>ng-transclude</code>, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.</p> -<h3> -<a id="interpreter" class="anchor" href="#interpreter" aria-hidden="true"><span class="octicon octicon-link"></span></a>Interpreter</h3> +<h4> +<a id="interpreter" class="anchor" href="#interpreter" aria-hidden="true"><span class="octicon octicon-link"></span></a>Interpreter</h4> <blockquote> <p>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.</p> @@ -768,7 +763,7 @@ <h3> <p>Inside the <code>$parse</code> service are defined two main components:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-c">//Responsible for converting given string into tokens</span> +<div class="highlight highlight-source-js"><pre><span class="pl-c">//Responsible for converting given string into tokens</span> <span class="pl-k">var</span> Lexer; <span class="pl-c">//Responsible for parsing the tokens and evaluating the expression</span> <span class="pl-k">var</span> Parser;</pre></div> @@ -777,7 +772,7 @@ <h3> <p>The terminal expressions in the AngularJS DSL are defined as follows:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">var</span> <span class="pl-c1">OPERATORS</span> <span class="pl-k">=</span> { +<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">OPERATORS</span> <span class="pl-k">=</span> { <span class="pl-c">/* jshint bitwise : false */</span> <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">null</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(){<span class="pl-k">return</span> <span class="pl-c1">null</span>;}, <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">true</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(){<span class="pl-k">return</span> <span class="pl-c1">true</span>;}, @@ -786,24 +781,24 @@ <h3> <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">+</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){ <span class="pl-c">//...</span> }, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">*</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">*</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">/</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)/<span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">%</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">%</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">^</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">^</span><span class="pl-c1">b</span>(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">*</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">*</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">/</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">/</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">%</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">%</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">^</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">^</span>b(self, locals);}, <span class="pl-s"><span class="pl-pds">'</span>=<span class="pl-pds">'</span></span><span class="pl-k">:</span>noop, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">===</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>, <span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">===</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!==</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>, <span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">!==</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">==</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">==</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">!=</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en"><</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k"><</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">></span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">></span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en"><=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k"><=</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">>=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">>=</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">&&</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">&&</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">||</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">||</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">&</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">a</span>(self, locals)<span class="pl-k">&</span><span class="pl-c1">b</span>(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">|</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> <span class="pl-c1">b</span>(self, locals)(self, locals, <span class="pl-c1">a</span>(self, locals));}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>){<span class="pl-k">return</span> <span class="pl-k">!</span><span class="pl-c1">a</span>(self, locals);} + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">===</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>, <span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">===</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!==</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>, <span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">!==</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">==</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">==</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">!=</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en"><</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k"><</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">></span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">></span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en"><=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k"><=</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">>=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">>=</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">&&</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">&&</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">||</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">||</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">&</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">&</span>b(self, locals);}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">|</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> b(self, locals)(self, locals, a(self, locals));}, + <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>){<span class="pl-k">return</span> <span class="pl-k">!</span>a(self, locals);} };</pre></div> <p>We can think of the function associated with each terminal as implementation of the <code>AbstractExpression</code>'s interface.</p> @@ -812,7 +807,7 @@ <h3> <p>Few sample AngularJS expressions are:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-c">// toUpperCase filter is applied to the result of the expression</span> +<div class="highlight highlight-source-js"><pre><span class="pl-c">// toUpperCase filter is applied to the result of the expression</span> <span class="pl-c">// (foo) ? bar : baz</span> (foo) <span class="pl-k">?</span> bar <span class="pl-k">:</span> baz | toUpperCase</pre></div> @@ -834,18 +829,18 @@ <h4> <p>For example:</p> -<div class="highlight highlight-html"><pre><span class="pl-s1"><<span class="pl-ent">script</span> <span class="pl-e">type</span>=<span class="pl-s"><span class="pl-pds">"</span>template/mustache<span class="pl-pds">"</span></span>></span> -<span class="pl-s1"> <span class="pl-k"><</span>h2<span class="pl-k">></span>Names<span class="pl-k"><</span>/h2<span class="pl-k">></span></span> +<div class="highlight highlight-text-html-basic"><pre><span class="pl-s1"><<span class="pl-ent">script</span> <span class="pl-e">type</span>=<span class="pl-s"><span class="pl-pds">"</span>template/mustache<span class="pl-pds">"</span></span>></span> +<span class="pl-s1"> <span class="pl-k"><</span>h2<span class="pl-k">></span>Names<span class="pl-k"></</span>h2<span class="pl-k">></span></span> <span class="pl-s1"> {{#names}}</span> -<span class="pl-s1"> <span class="pl-k"><</span>strong<span class="pl-k">></span>{{name}}<span class="pl-k"><</span>/strong<span class="pl-k">></span></span> -<span class="pl-s1"> {{/names}}</span> +<span class="pl-s1"> <span class="pl-k"><</span>strong<span class="pl-k">></span>{{name}}<span class="pl-k"></</span>strong<span class="pl-k">></span></span> +<span class="pl-s1"> {{<span class="pl-k">/</span>names}}</span> <span class="pl-s1"></<span class="pl-ent">script</span>></span></pre></div> <p>The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.</p> <p>For example if we evaluate the template above in the context of the following object: <code>{ names: ['foo', 'bar', 'baz'] }</code>, so we will get:</p> -<div class="highlight highlight-html"><pre><<span class="pl-ent">h2</span>>Names</<span class="pl-ent">h2</span>> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">h2</span>>Names</<span class="pl-ent">h2</span>> <<span class="pl-ent">strong</span>>foo</<span class="pl-ent">strong</span>> <<span class="pl-ent">strong</span>>bar</<span class="pl-ent">strong</span>> <<span class="pl-ent">strong</span>>baz</<span class="pl-ent">strong</span>></pre></div> @@ -855,13 +850,13 @@ <h4> <p>For example:</p> -<div class="highlight highlight-html"><pre><<span class="pl-ent">ul</span> <span class="pl-e">ng-repeat</span>=<span class="pl-s"><span class="pl-pds">"</span>name in names<span class="pl-pds">"</span></span>> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">ul</span> <span class="pl-e">ng-repeat</span>=<span class="pl-s"><span class="pl-pds">"</span>name in names<span class="pl-pds">"</span></span>> <<span class="pl-ent">li</span>>{{name}}</<span class="pl-ent">li</span>> </<span class="pl-ent">ul</span>></pre></div> <p>in the context of the scope:</p> -<div class="highlight highlight-javascript"><pre>$scope.<span class="pl-c1">names</span> <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>baz<span class="pl-pds">'</span></span>];</pre></div> +<div class="highlight highlight-source-js"><pre>$scope.names <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>baz<span class="pl-pds">'</span></span>];</pre></div> <p>will produce the same result as the one above. The main difference here is that the template is not wrapped inside a <code>script</code> tag but is HTML instead.</p> @@ -881,8 +876,8 @@ <h4> <p>Each AngularJS scope has public methods called <code>$on</code>, <code>$emit</code> and <code>$broadcast</code>. The method <code>$on</code> accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the <code>Observer</code> interface (in JavaScript the functions are first-class, so we can provide only implementation of the <code>notify</code> method):</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">ExampleCtrl</span>(<span class="pl-smi">$scope</span>) { - $scope.$<span class="pl-c1">on</span>(<span class="pl-s"><span class="pl-pds">'</span>event-name<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> <span class="pl-en">handler</span>() { +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">ExampleCtrl</span>(<span class="pl-smi">$scope</span>) { + $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>event-name<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> <span class="pl-en">handler</span>() { <span class="pl-c">//body</span> }); }</pre></div> @@ -892,8 +887,8 @@ <h4> <p>The methods <code>$emit</code> and <code>$broadcast</code> are used for triggering events respectively upwards and downwards through the scope chain. For example:</p> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">ExampleCtrl</span>(<span class="pl-smi">$scope</span>) { - $scope.$<span class="pl-c1">emit</span>(<span class="pl-s"><span class="pl-pds">'</span>event-name<span class="pl-pds">'</span></span>, { foo<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span> }); +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">ExampleCtrl</span>(<span class="pl-smi">$scope</span>) { + $scope.$emit(<span class="pl-s"><span class="pl-pds">'</span>event-name<span class="pl-pds">'</span></span>, { foo<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span> }); }</pre></div> <p>The scope in the example above, triggers the event <code>event-name</code> to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event <code>event-name</code>, would be notified and their handler callback will be invoked.</p> @@ -927,20 +922,20 @@ <h4> <p>In the example bellow you can see an example in which <code>ChildCtrl</code> triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in <code>ParentCtrl</code> and the one used in <code>MainCtrl</code>) are going to handle the event by logging into the console: <code>"foo received"</code>. If any of the scopes should be considered as final destination it can call the method <code>stopPropagation</code> of the event object, passed to the callback.</p> -<div class="highlight highlight-JavaScript"><pre>myModule.<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { - $scope.$<span class="pl-c1">on</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { +<div class="highlight highlight-source-js"><pre>myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { + $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); }); }); -myModule.<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>ParentCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { - $scope.$<span class="pl-c1">on</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">e</span>) { +myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>ParentCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { + $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">e</span>) { <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); }); }); -myModule.<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>ChildCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { - $scope.$<span class="pl-c1">emit</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>); +myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>ChildCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { + $scope.$emit(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>); });</pre></div> <p>The different handlers from the UML diagram above are the different scopes, injected to the controllers.</p> @@ -958,11 +953,11 @@ <h4> <p>When we want to bind our model to the view we use the directives <code>ng-bind</code> (for single-way data binding) and <code>ng-model</code> (for two-way data binding). For example, if we want each change in the model <code>foo</code> to reflect the view we can:</p> -<div class="highlight highlight-html"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>foo<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>foo<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> <p>Now each time we change the value of <code>foo</code> the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:</p> -<div class="highlight highlight-html"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>foo + ' ' + bar | uppercase<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>foo + ' ' + bar | uppercase<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> <p>In the example above the value of the span will be the concatenated uppercased value of <code>foo</code> and <code>bar</code>. What happens behind the scene?</p> @@ -970,9 +965,9 @@ <h4> <p>Here are the first a couple of lines of the implementation of <code>$watch</code>:</p> -<div class="highlight highlight-javascript"><pre>$<span class="pl-en">watch</span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">watchExp</span>, <span class="pl-smi">listener</span>, <span class="pl-smi">objectEquality</span>) { +<div class="highlight highlight-source-js"><pre>$<span class="pl-en">watch</span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">watchExp</span>, <span class="pl-smi">listener</span>, <span class="pl-smi">objectEquality</span>) { <span class="pl-k">var</span> scope <span class="pl-k">=</span> <span class="pl-v">this</span>, - get <span class="pl-k">=</span> <span class="pl-c1">compileToFn</span>(watchExp, <span class="pl-s"><span class="pl-pds">'</span>watch<span class="pl-pds">'</span></span>), + get <span class="pl-k">=</span> compileToFn(watchExp, <span class="pl-s"><span class="pl-pds">'</span>watch<span class="pl-pds">'</span></span>), array <span class="pl-k">=</span> scope.$$watchers, watcher <span class="pl-k">=</span> { fn<span class="pl-k">:</span> listener, @@ -1010,7 +1005,7 @@ <h4> <p>The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap. Here is an example hierarchy between few controllers:</p> -<div class="highlight highlight-HTML"><pre><!doctype html> +<div class="highlight highlight-text-html-basic"><pre><!doctype html> <<span class="pl-ent">html</span>> <<span class="pl-ent">head</span>> </<span class="pl-ent">head</span>> @@ -1022,9 +1017,9 @@ <h4> </<span class="pl-ent">body</span>> </<span class="pl-ent">html</span>></pre></div> -<div class="highlight highlight-JavaScript"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">$location</span>, <span class="pl-smi">User</span>) { - <span class="pl-k">if</span> (<span class="pl-k">!</span>User.<span class="pl-c1">isAuthenticated</span>()) { - $location.<span class="pl-c1">path</span>(<span class="pl-s"><span class="pl-pds">'</span>/unauthenticated<span class="pl-pds">'</span></span>); +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">$location</span>, <span class="pl-smi">User</span>) { + <span class="pl-k">if</span> (<span class="pl-k">!</span>User.isAuthenticated()) { + $location.path(<span class="pl-s"><span class="pl-pds">'</span>/unauthenticated<span class="pl-pds">'</span></span>); } } @@ -1032,7 +1027,7 @@ <h4> <span class="pl-c1">$scope</span>.<span class="pl-en">click</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>You clicked me!<span class="pl-pds">'</span></span>); }; - $scope.<span class="pl-c1">user</span> <span class="pl-k">=</span> User.<span class="pl-c1">get</span>(<span class="pl-c1">0</span>); + $scope.user <span class="pl-k">=</span> User.get(<span class="pl-c1">0</span>); }</pre></div> <p>This example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.</p> @@ -1049,7 +1044,7 @@ <h4> <p>Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:</p> -<div class="highlight highlight-javascript"><pre><span class="pl-k">var</span> Page <span class="pl-k">=</span> (<span class="pl-k">function</span> () { +<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> Page <span class="pl-k">=</span> (<span class="pl-k">function</span> () { <span class="pl-k">var</span> title; @@ -1074,7 +1069,7 @@ <h4> <p>The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:</p> -<div class="highlight highlight-javascript"><pre>app.<span class="pl-c1">factory</span>(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { +<div class="highlight highlight-source-js"><pre>app.factory(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-k">function</span> <span class="pl-en">privateMember</span>() { <span class="pl-c">//body...</span> @@ -1082,7 +1077,7 @@ <h4> <span class="pl-k">function</span> <span class="pl-en">publicMember</span>() { <span class="pl-c">//body...</span> - <span class="pl-c1">privateMember</span>(); + privateMember(); <span class="pl-c">//body</span> } @@ -1093,8 +1088,8 @@ <h4> <p>Once we want to inject <code>foo</code> inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.</p> -<h3> -<a id="data-mapper" class="anchor" href="#data-mapper" aria-hidden="true"><span class="octicon octicon-link"></span></a>Data Mapper</h3> +<h4> +<a id="data-mapper" class="anchor" href="#data-mapper" aria-hidden="true"><span class="octicon octicon-link"></span></a>Data Mapper</h4> <blockquote> <p>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.</p> @@ -1125,20 +1120,20 @@ <h3> <p>Possible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called <code>User</code>, which loads the user's friends when we request the user:</p> -<div class="highlight highlight-javascript"><pre>app.<span class="pl-c1">factory</span>(<span class="pl-s"><span class="pl-pds">'</span>User<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$q</span>) { +<div class="highlight highlight-source-js"><pre>app.factory(<span class="pl-s"><span class="pl-pds">'</span>User<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$q</span>) { <span class="pl-k">function</span> <span class="pl-en">User</span>(<span class="pl-smi">name</span>, <span class="pl-smi">address</span>, <span class="pl-smi">friends</span>) { <span class="pl-v">this</span>.<span class="pl-c1">name</span> <span class="pl-k">=</span> name; - <span class="pl-v">this</span>.<span class="pl-c1">address</span> <span class="pl-k">=</span> address; - <span class="pl-v">this</span>.<span class="pl-c1">friends</span> <span class="pl-k">=</span> friends; + <span class="pl-v">this</span>.address <span class="pl-k">=</span> address; + <span class="pl-v">this</span>.friends <span class="pl-k">=</span> friends; } <span class="pl-c1">User</span>.<span class="pl-en">get</span> <span class="pl-k">=</span> <span class="pl-k">function</span> (<span class="pl-smi">params</span>) { - <span class="pl-k">var</span> user <span class="pl-k">=</span> $http.<span class="pl-c1">get</span>(<span class="pl-s"><span class="pl-pds">'</span>/user/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> params.<span class="pl-c1">id</span>), - friends <span class="pl-k">=</span> $http.<span class="pl-c1">get</span>(<span class="pl-s"><span class="pl-pds">'</span>/friends/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> params.<span class="pl-c1">id</span>); + <span class="pl-k">var</span> user <span class="pl-k">=</span> $http.get(<span class="pl-s"><span class="pl-pds">'</span>/user/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> params.<span class="pl-c1">id</span>), + friends <span class="pl-k">=</span> $http.get(<span class="pl-s"><span class="pl-pds">'</span>/friends/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> params.<span class="pl-c1">id</span>); $q.<span class="pl-c1">all</span>([user, friends]) - .<span class="pl-c1">then</span>(<span class="pl-k">function</span> (<span class="pl-smi">user</span>, <span class="pl-smi">friends</span>) { - <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-en">User</span>(user.<span class="pl-c1">name</span>, user.<span class="pl-c1">address</span>, friends); + .then(<span class="pl-k">function</span> (<span class="pl-smi">user</span>, <span class="pl-smi">friends</span>) { + <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-en">User</span>(user.<span class="pl-c1">name</span>, user.address, friends); }); }; <span class="pl-k">return</span> User; @@ -1148,16 +1143,16 @@ <h3> <p>We can use the <code>User</code> service by:</p> -<div class="highlight highlight-javascript"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">User</span>) { - User.<span class="pl-c1">get</span>({ id<span class="pl-k">:</span> <span class="pl-c1">1</span> }) - .<span class="pl-c1">then</span>(<span class="pl-k">function</span> (<span class="pl-smi">data</span>) { - $scope.<span class="pl-c1">user</span> <span class="pl-k">=</span> data; +<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">User</span>) { + User.get({ id<span class="pl-k">:</span> <span class="pl-c1">1</span> }) + .then(<span class="pl-k">function</span> (<span class="pl-smi">data</span>) { + $scope.user <span class="pl-k">=</span> data; }); }</pre></div> <p>And the following partial:</p> -<div class="highlight highlight-html"><pre><<span class="pl-ent">div</span>> +<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">div</span>> <<span class="pl-ent">div</span>> Name: {{user.name}} </<span class="pl-ent">div</span>> @@ -1172,8 +1167,8 @@ <h3> </<span class="pl-ent">div</span>> </<span class="pl-ent">div</span>></pre></div> -<h3> -<a id="observer-pattern-as-an-external-service" class="anchor" href="#observer-pattern-as-an-external-service" aria-hidden="true"><span class="octicon octicon-link"></span></a>Observer Pattern as an External Service</h3> +<h4> +<a id="observer-pattern-as-an-external-service" class="anchor" href="#observer-pattern-as-an-external-service" aria-hidden="true"><span class="octicon octicon-link"></span></a>Observer Pattern as an External Service</h4> <h5> <a id="about" class="anchor" href="#about" aria-hidden="true"><span class="octicon octicon-link"></span></a>About</h5> @@ -1187,48 +1182,48 @@ <h5> <p>Below example shows how to attach, notify and detach an event.</p> -<div class="highlight highlight-javascript"><pre>angular.<span class="pl-c1">module</span>(<span class="pl-s"><span class="pl-pds">'</span>app.controllers<span class="pl-pds">'</span></span>) - .<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>ObserverExample<span class="pl-pds">'</span></span>, ObserverExample); +<div class="highlight highlight-source-js"><pre>angular.module(<span class="pl-s"><span class="pl-pds">'</span>app.controllers<span class="pl-pds">'</span></span>) + .controller(<span class="pl-s"><span class="pl-pds">'</span>ObserverExample<span class="pl-pds">'</span></span>, ObserverExample); ObserverExample.$inject<span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>ObserverService<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$timeout<span class="pl-pds">'</span></span>]; <span class="pl-k">function</span> <span class="pl-en">ObserverExample</span>(<span class="pl-smi">ObserverService</span>, <span class="pl-smi">$timeout</span>) { <span class="pl-k">var</span> vm <span class="pl-k">=</span> <span class="pl-v">this</span>; <span class="pl-k">var</span> id <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>vm1<span class="pl-pds">'</span></span>; - ObserverService.<span class="pl-c1">attach</span>(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) + ObserverService.attach(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) <span class="pl-k">function</span> <span class="pl-en">callbackFunction</span>(<span class="pl-smi">params</span>){ <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); - ObserverService.<span class="pl-c1">detachByEvent</span>(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) + ObserverService.detachByEvent(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) } - $<span class="pl-c1">timeout</span>(<span class="pl-k">function</span>(){ - ObserverService.<span class="pl-c1">notify</span>(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>); + $timeout(<span class="pl-k">function</span>(){ + ObserverService.notify(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>); }, <span class="pl-c1">5000</span>); }</pre></div> <p>Alternative way to remove event</p> -<div class="highlight highlight-javascript"><pre>angular.<span class="pl-c1">module</span>(<span class="pl-s"><span class="pl-pds">'</span>app.controllers<span class="pl-pds">'</span></span>) - .<span class="pl-c1">controller</span>(<span class="pl-s"><span class="pl-pds">'</span>ObserverExample<span class="pl-pds">'</span></span>, ObserverExample); +<div class="highlight highlight-source-js"><pre>angular.module(<span class="pl-s"><span class="pl-pds">'</span>app.controllers<span class="pl-pds">'</span></span>) + .controller(<span class="pl-s"><span class="pl-pds">'</span>ObserverExample<span class="pl-pds">'</span></span>, ObserverExample); ObserverExample.$inject<span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>ObserverService<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$timeout<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$scope<span class="pl-pds">'</span></span>]; <span class="pl-k">function</span> <span class="pl-en">ObserverExample</span>(<span class="pl-smi">ObserverService</span>, <span class="pl-smi">$timeout</span>, <span class="pl-smi">$scope</span>) { <span class="pl-k">var</span> vm <span class="pl-k">=</span> <span class="pl-v">this</span>; <span class="pl-k">var</span> id <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>vm1<span class="pl-pds">'</span></span>; - ObserverService.<span class="pl-c1">attach</span>(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) + ObserverService.attach(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) <span class="pl-k">function</span> <span class="pl-en">callbackFunction</span>(<span class="pl-smi">params</span>){ <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); } - $<span class="pl-c1">timeout</span>(<span class="pl-k">function</span>(){ - ObserverService.<span class="pl-c1">notify</span>(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>); + $timeout(<span class="pl-k">function</span>(){ + ObserverService.notify(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>); }, <span class="pl-c1">5000</span>); <span class="pl-c">// Cleanup listeners when this controller is destroyed</span> - $scope.$<span class="pl-c1">on</span>(<span class="pl-s"><span class="pl-pds">'</span>$destroy<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> <span class="pl-en">handler</span>() { - ObserverService.<span class="pl-c1">detachByEvent</span>(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) + $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>$destroy<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> <span class="pl-en">handler</span>() { + ObserverService.detachByEvent(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) }); }</pre></div> diff --git a/params.json b/params.json index 50f31d4..f0d2456 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"AngularJS in Patterns","tagline":"\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.","body":"# AngularJS in Patterns\r\n\r\n<!--toc-->\r\n\r\n## Table of Contents\r\n\r\n* [Translations](#translations)\r\n* [Abstract](#abstract)\r\n* [Introduction](#introduction)\r\n* [AngularJS overview](#angularjs-overview)\r\n * [Partials](#partials)\r\n * [Controllers](#controllers)\r\n * [Scope](#scope)\r\n * [Directives](#directives)\r\n * [Filters](#filters)\r\n * [Services](#services)\r\n* [AngularJS Patterns](#angularjs-patterns)\r\n * [Services](#services-1)\r\n * [Singleton](#singleton)\r\n * [Factory Method](#factory-method)\r\n * [Decorator](#decorator)\r\n * [Facade](#facade)\r\n * [Proxy](#proxy)\r\n * [Active Record](#active-record)\r\n * [Intercepting Filters](#intercepting-filters)\r\n * [Directives](#directives-1)\r\n * [Composite](#composite)\r\n * [Interpreter](#interpreter)\r\n * [Template View](#template-view)\r\n * [Scope](#scope-1)\r\n * [Observer](#observer)\r\n * [Chain of Responsibilities](#chain-of-responsibilities)\r\n * [Command](#command)\r\n * [Controller](#controller-1)\r\n * [Page Controller](#page-controller)\r\n * [Others](#others)\r\n * [Module Pattern](#module-pattern)\r\n * [Data Mapper](#data-mapper)\r\n * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n* [References](#references)\r\n\r\n<!--endtoc-->\r\n\r\n## Translations\r\n\r\n- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter)\r\n- [Russian Translation](http://habrahabr.ru/post/250149/)\r\n- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko)\r\n\r\n## Abstract\r\n\r\nOne of the best ways to learn something new is to see how the things you already know are used in it.\r\nThis document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns.\r\nThe goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.\r\n\r\n## Introduction\r\n\r\nThe document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.\r\n\r\nThe last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.\r\n\r\n## AngularJS overview\r\n\r\nAngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA).\r\nSPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand.\r\nSince most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:\r\n\r\n- two-way data binding\r\n- dependency injection\r\n- separation of concerns\r\n- testability\r\n- abstraction\r\n\r\nThe separation of concerns is achieved by dividing each AngularJS application into separate components, such as:\r\n\r\n- partials\r\n- controllers\r\n- directives\r\n- services\r\n- filters\r\n\r\nThese components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.\r\n\r\n### Partials\r\n\r\nThe partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).\r\n\r\nInitially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.\r\n\r\n**Sample partial**\r\n\r\n```HTML\r\n<html ng-app>\r\n <!-- Body tag augmented with ngController directive -->\r\n <body ng-controller=\"MyController\">\r\n <input ng-model=\"foo\" value=\"bar\">\r\n <!-- Button tag with ng-click directive, and\r\n string expression 'buttonText'\r\n wrapped in \"{{ }}\" markup -->\r\n <button ng-click=\"changeFoo()\">{{buttonText}}</button>\r\n <script src=\"angular.js\"></script>\r\n </body>\r\n</html>\r\n```\r\n\r\nWith AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked.\r\n\r\n### Controllers\r\n\r\nThe AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*.\r\n\r\n```JavaScript\r\nfunction MyController($scope) {\r\n $scope.buttonText = 'Click me to change foo!';\r\n $scope.foo = 42;\r\n\r\n $scope.changeFoo = function () {\r\n $scope.foo += 1;\r\n alert('Foo changed');\r\n };\r\n}\r\n```\r\n\r\nFor example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.\r\n\r\n1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding.\r\n2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`.\r\n\r\nAll the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones.\r\n\r\n### Scope\r\n\r\nIn AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.\r\n\r\nAnother important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.\r\n\r\nScope inheritance is illustrated in the following example:\r\n\r\n```HTML\r\n<div ng-controller=\"BaseCtrl\">\r\n <div id=\"child\" ng-controller=\"ChildCtrl\">\r\n <button id=\"parent-method\" ng-click=\"foo()\">Parent method</button>\r\n <button ng-click=\"bar()\">Child method</button>\r\n </div>\r\n</div>\r\n```\r\n\r\n```JavaScript\r\nfunction BaseCtrl($scope) {\r\n $scope.foo = function () {\r\n alert('Base foo');\r\n };\r\n}\r\n\r\nfunction ChildCtrl($scope) {\r\n $scope.bar = function () {\r\n alert('Child bar');\r\n };\r\n}\r\n```\r\n\r\nWith `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`.\r\n\r\n### Directives\r\n\r\nIn AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations.\r\nEach directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:\r\n\r\n- template\r\n- compile function\r\n- link function\r\n- etc...\r\n\r\nBy citing the name of the directives they can be used inside the declarative partials.\r\n\r\nExample:\r\n\r\n```JavaScript\r\nmyModule.directive('alertButton', function () {\r\n return {\r\n template: '<button ng-transclude></button>',\r\n scope: {\r\n content: '@'\r\n },\r\n replace: true,\r\n restrict: 'E',\r\n transclude: true,\r\n link: function (scope, el) {\r\n el.click(function () {\r\n alert(scope.content);\r\n });\r\n }\r\n };\r\n});\r\n```\r\n\r\n```HTML\r\n<alert-button content=\"42\">Click me</alert-button>\r\n```\r\n\r\nIn the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted.\r\n\r\nSince the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.\r\n\r\n### Filters\r\n\r\nThe filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection.\r\n\r\nHere is a definition of a sample filter, which changes the given string to uppercase:\r\n\r\n```JavaScript\r\nmyModule.filter('uppercase', function () {\r\n return function (str) {\r\n return (str || '').toUpperCase();\r\n };\r\n});\r\n```\r\n\r\nInside a partial this filter could be used using the Unix's piping syntax:\r\n\r\n```HTML\r\n<div>{{ name | uppercase }}</div>\r\n```\r\n\r\nInside a controller the filter could be used as follows:\r\n\r\n```JavaScript\r\nfunction MyCtrl(uppercaseFilter) {\r\n $scope.name = uppercaseFilter('foo'); //FOO\r\n}\r\n```\r\n\r\n### Services\r\n\r\nEvery piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too \"fat\" the repetitive code should be placed inside a service.\r\n\r\n```JavaScript\r\nmyModule.service('Developer', function () {\r\n this.name = 'Foo';\r\n this.motherLanguage = 'JavaScript';\r\n this.live = function () {\r\n while (true) {\r\n this.code();\r\n }\r\n };\r\n});\r\n```\r\n\r\nThe service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).\r\n\r\n```JavaScript\r\nfunction MyCtrl(Developer) {\r\n var developer = new Developer();\r\n developer.live();\r\n}\r\n```\r\n\r\n## AngularJS Patterns\r\n\r\nIn the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.\r\n\r\nIn the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.\r\n\r\n### Services\r\n\r\n#### Singleton\r\n\r\n>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.\r\n\r\nIn the UML diagram bellow is illustrated the singleton design pattern.\r\n\r\n\r\n\r\nWhen given dependency is required by any component, AngularJS resolves it using the following algorithm:\r\n\r\n- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).\r\n- If the dependency exists AngularJS pass it as parameter to the component, which requires it.\r\n- If the dependency does not exists:\r\n - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.\r\n - AngularJS caches it inside the hash map mentioned above.\r\n - AngularJS passes it as parameter to the component, which requires it.\r\n\r\nWe can take better look at the AngularJS' source code, which implements the method `getService`:\r\n\r\n```JavaScript\r\nfunction getService(serviceName) {\r\n if (cache.hasOwnProperty(serviceName)) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));\r\n }\r\n return cache[serviceName];\r\n } else {\r\n try {\r\n path.unshift(serviceName);\r\n cache[serviceName] = INSTANTIATING;\r\n return cache[serviceName] = factory(serviceName);\r\n } catch (err) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n delete cache[serviceName];\r\n }\r\n throw err;\r\n } finally {\r\n path.shift();\r\n }\r\n }\r\n}\r\n```\r\n\r\nWe can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`).\r\n\r\nThis way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:\r\n\r\n- It improves the testability of your source code\r\n- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)\r\n\r\nFor further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered.\r\n\r\n#### Factory Method\r\n\r\n>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.\r\n\r\n\r\n\r\nLets consider the following snippet:\r\n\r\n```JavaScript\r\nmyModule.config(function ($provide) {\r\n $provide.provider('foo', function () {\r\n var baz = 42;\r\n return {\r\n //Factory method\r\n $get: function (bar) {\r\n var baz = bar.baz();\r\n return {\r\n baz: baz\r\n };\r\n }\r\n };\r\n });\r\n});\r\n\r\n```\r\n\r\nIn the code above we use the `config` callback in order to define new \"provider\". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.\r\n\r\nEach service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.\r\n\r\nWe can dig a little bit deeper in AngularJS' implementation:\r\n\r\n```JavaScript\r\n//...\r\n\r\ncreateInternalInjector(instanceCache, function(servicename) {\r\n var provider = providerInjector.get(servicename + providerSuffix);\r\n return instanceInjector.invoke(provider.$get, provider, undefined, servicename);\r\n}, strictDi));\r\n\r\n//...\r\n\r\nfunction invoke(fn, self, locals, serviceName){\r\n if (typeof locals === 'string') {\r\n serviceName = locals;\r\n locals = null;\r\n }\r\n\r\n var args = [],\r\n $inject = annotate(fn, strictDi, serviceName),\r\n length, i,\r\n key;\r\n\r\n for(i = 0, length = $inject.length; i < length; i++) {\r\n key = $inject[i];\r\n if (typeof key !== 'string') {\r\n throw $injectorMinErr('itkn',\r\n 'Incorrect injection token! Expected service name as string, got {0}', key);\r\n }\r\n args.push(\r\n locals && locals.hasOwnProperty(key)\r\n ? locals[key]\r\n : getService(key)\r\n );\r\n }\r\n if (!fn.$inject) {\r\n // this means that we must be an array.\r\n fn = fn[length];\r\n }\r\n\r\n return fn.apply(self, args);\r\n}\r\n```\r\n\r\nFrom the example above we can notice how the `$get` method is actually used:\r\n\r\n```JavaScript\r\ninstanceInjector.invoke(provider.$get, provider, undefined, servicename)\r\n```\r\n\r\nThe snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.\r\n\r\nIf we think in terms of the UML diagram above we can call the provider a \"ConcreteCreator\" and the actual component, which is being created a \"Product\".\r\n\r\nThere are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:\r\n\r\n- The most appropriate moment, when the component needs to be instantiated\r\n- Resolving all the dependencies required by the component\r\n- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)\r\n\r\n#### Decorator\r\n\r\n>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.\r\n\r\n\r\n\r\nAngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create \"wrapper\" of any service you have previously defined or used by a third-party:\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function (foo) {\r\n foo.bar();\r\n});\r\n\r\nmyModule.factory('foo', function () {\r\n return {\r\n bar: function () {\r\n console.log('I\\'m bar');\r\n },\r\n baz: function () {\r\n console.log('I\\'m baz');\r\n }\r\n };\r\n});\r\n\r\nmyModule.config(function ($provide) {\r\n $provide.decorator('foo', function ($delegate) {\r\n var barBackup = $delegate.bar;\r\n $delegate.bar = function () {\r\n console.log('Decorated');\r\n barBackup.apply($delegate, arguments);\r\n };\r\n return $delegate;\r\n });\r\n});\r\n```\r\nThe example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `\"foo\"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.\r\nWe decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.\r\n\r\nUsing this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop).\r\n\r\n#### Facade\r\n\r\n>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:\r\n\r\n>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;\r\n\r\n>2. make the library more readable, for the same reason;\r\n\r\n>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;\r\n\r\n>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).\r\n\r\n\r\n\r\nThere are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.\r\n\r\nFor example, lets take a look how we can create an `XMLHttpRequest` POST request:\r\n\r\n```JavaScript\r\nvar http = new XMLHttpRequest(),\r\n url = '/example/new',\r\n params = encodeURIComponent(data);\r\nhttp.open(\"POST\", url, true);\r\n\r\nhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\r\nhttp.setRequestHeader(\"Content-length\", params.length);\r\nhttp.setRequestHeader(\"Connection\", \"close\");\r\n\r\nhttp.onreadystatechange = function () {\r\n if(http.readyState == 4 && http.status == 200) {\r\n alert(http.responseText);\r\n }\r\n}\r\nhttp.send(params);\r\n```\r\nBut if we want to post this data using the AngularJS' `$http` service we can:\r\n\r\n```JavaScript\r\n$http({\r\n method: 'POST',\r\n url: '/example/new',\r\n data: data\r\n})\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nor we can even:\r\n\r\n```JavaScript\r\n$http.post('/someUrl', data)\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nThe second option provides pre-configured version, which creates a HTTP POST request to the given URL.\r\n\r\nEven higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections.\r\n\r\n#### Proxy\r\n\r\n>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.\r\n\r\n\r\n\r\nWe can distinguish three different types of proxy:\r\n\r\n- Virtual Proxy\r\n- Remote Proxy\r\n- Protection Proxy\r\n\r\nIn this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.\r\n\r\nIn the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = User.get({ id: 42 });\r\nconsole.log(user); //{}\r\n```\r\n\r\n`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.\r\n\r\nHow does this works with AngularJS? Well, lets consider the following snippet:\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $resource) {\r\n var User = $resource('/users/:id'),\r\n $scope.user = User.get({ id: 42 });\r\n}\r\n```\r\n\r\n```html\r\n<span ng-bind=\"user.name\"></span>\r\n```\r\nInitially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view.\r\n\r\n#### Active Record\r\n\r\n>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.\r\n\r\n\r\n\r\nAngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.\r\n\r\nAccording to the AngularJS' documentation `$resource` is:\r\n\r\n>A factory which creates a resource object that lets you interact with RESTful server-side data sources.\r\n>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.\r\n\r\nHere is how `$resource` could be used:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = new User({\r\n name: 'foo',\r\n age : 42\r\n });\r\n\r\nuser.$save();\r\n```\r\n\r\nThe call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.\r\n\r\nThis way we can use the constructor function and its static methods by:\r\n\r\n```JavaScript\r\nUser.get({ userid: userid });\r\n```\r\n\r\nThe code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)).\r\n\r\nYou can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource).\r\n\r\nSince Martin Fowler states that\r\n\r\n> responsibility of the Active Record object is to take care of the communication with the databse in order to create...\r\n\r\n`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as \"Active Record like RESTful communication\".\r\n\r\n#### Intercepting Filters\r\n\r\n>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.\r\n\r\n\r\n\r\nIn some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.\r\n\r\nIn AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`.\r\n\r\n`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error.\r\n\r\nHere is a basic example how you can add interceptors using object literal:\r\n\r\n```JavaScript\r\n$httpProvider.interceptors.push(function($q, dependency1, dependency2) {\r\n return {\r\n 'request': function(config) {\r\n // same as above\r\n },\r\n 'response': function(response) {\r\n // same as above\r\n }\r\n };\r\n});\r\n```\r\n\r\n### Directives\r\n\r\n#### Composite\r\n\r\n>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to \"compose\" objects into tree structures to represent part-whole hierarchies.\r\n\r\n\r\n\r\nAccording to the Gang of Four, MVC is nothing more than combination of:\r\n\r\n- Strategy\r\n- Composite\r\n- Observer\r\n\r\nThey state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.\r\n\r\nLets look at the following example:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body>\r\n <zippy title=\"Zippy\">\r\n Zippy!\r\n </zippy>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nmyModule.directive('zippy', function () {\r\n return {\r\n restrict: 'E',\r\n template: '<div><div class=\"header\"></div><div class=\"content\" ng-transclude></div></div>',\r\n link: function (scope, el) {\r\n el.find('.header').click(function () {\r\n el.find('.content').toggle();\r\n });\r\n }\r\n }\r\n});\r\n```\r\n\r\nThis example defines a simple directive, which is a UI component. The defined component (called \"zippy\") has header and content. Click on its header toggles the visibility of the content.\r\n\r\nFrom the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on...\r\n\r\nIn the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.\r\n\r\n### Interpreter\r\n\r\n>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.\r\n\r\n\r\n\r\nBehind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript.\r\nThe main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:\r\n\r\n- may contain filters with UNIX like pipe syntax\r\n- don't throw any errors\r\n- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)\r\n- are evaluated in given context (the context of the current `$scope`)\r\n\r\nInside the `$parse` service are defined two main components:\r\n\r\n```JavaScript\r\n//Responsible for converting given string into tokens\r\nvar Lexer;\r\n//Responsible for parsing the tokens and evaluating the expression\r\nvar Parser;\r\n```\r\n\r\nOnce given expression have been tokenized it is cached internally, because of performance concerns.\r\n\r\nThe terminal expressions in the AngularJS DSL are defined as follows:\r\n\r\n```JavaScript\r\nvar OPERATORS = {\r\n /* jshint bitwise : false */\r\n 'null':function(){return null;},\r\n 'true':function(){return true;},\r\n 'false':function(){return false;},\r\n undefined:noop,\r\n '+':function(self, locals, a,b){\r\n //...\r\n },\r\n '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},\r\n '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},\r\n '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},\r\n '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},\r\n '=':noop,\r\n '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},\r\n '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},\r\n '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},\r\n '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},\r\n '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},\r\n '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},\r\n '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},\r\n '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},\r\n '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},\r\n '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},\r\n '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},\r\n '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},\r\n '!':function(self, locals, a){return !a(self, locals);}\r\n};\r\n```\r\n\r\nWe can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface.\r\n\r\nEach `Client` interprets given AngularJS expression in a specific context - specific scope.\r\n\r\nFew sample AngularJS expressions are:\r\n\r\n```JavaScript\r\n// toUpperCase filter is applied to the result of the expression\r\n// (foo) ? bar : baz\r\n(foo) ? bar : baz | toUpperCase\r\n```\r\n\r\n#### Template View\r\n\r\n> Renders information into HTML by embedding markers in an HTML page.\r\n\r\n\r\n\r\nThe dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.\r\n\r\nTemplates are very commonly used especially in the back-end.\r\nFor example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.\r\n\r\nFor JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript.\r\n\r\nFor example:\r\n\r\n```html\r\n<script type=\"template/mustache\">\r\n <h2>Names</h2>\r\n {{#names}}\r\n <strong>{{name}}</strong>\r\n {{/names}}\r\n</script>\r\n```\r\n\r\nThe template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.\r\n\r\nFor example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get:\r\n\r\n```html\r\n<h2>Names</h2>\r\n <strong>foo</strong>\r\n <strong>bar</strong>\r\n <strong>baz</strong>\r\n```\r\n\r\nAngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are.\r\nWhat AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.\r\n\r\nFor example:\r\n\r\n```html\r\n<ul ng-repeat=\"name in names\">\r\n <li>{{name}}</li>\r\n</ul>\r\n```\r\n\r\nin the context of the scope:\r\n\r\n```javascript\r\n$scope.names = ['foo', 'bar', 'baz'];\r\n```\r\n\r\nwill produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead.\r\n\r\n\r\n### Scope\r\n\r\n#### Observer\r\n\r\n>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.\r\n\r\n\r\n\r\nThere are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.\r\n\r\nEach AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$on('event-name', function handler() {\r\n //body\r\n });\r\n}\r\n```\r\n\r\nIn this way the current scope \"subscribes\" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.\r\n\r\nThe methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.\r\nFor example:\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$emit('event-name', { foo: 'bar' });\r\n}\r\n```\r\n\r\nThe scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.\r\n\r\nAnalogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.\r\nEach scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).\r\n\r\nIn the JavaScript community this pattern is better known as publish/subscribe.\r\n\r\nFor a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n\r\n#### Chain of Responsibilities\r\n\r\n>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.\r\n\r\n\r\n\r\nAs stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are \"isolated\", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.\r\n\r\nWhen `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:\r\n\r\n- Handle the event and pass it to the next scope in the chain\r\n- Handle the event and stop its propagation\r\n- Pass the event to the next scope in the chain without handling it\r\n- Stop the event propagation without handling it\r\n\r\nIn the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `\"foo received\"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback.\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function ($scope) {\r\n $scope.$on('foo', function () {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ParentCtrl', function ($scope) {\r\n $scope.$on('foo', function (e) {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ChildCtrl', function ($scope) {\r\n $scope.$emit('foo');\r\n});\r\n```\r\n\r\nThe different handlers from the UML diagram above are the different scopes, injected to the controllers.\r\n\r\n#### Command\r\n\r\n>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.\r\n\r\n\r\n\r\nBefore continuing with the application of the command pattern lets describe how AngularJS implements data binding.\r\n\r\nWhen we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can:\r\n\r\n```html\r\n<span ng-bind=\"foo\"></span>\r\n```\r\n\r\nNow each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:\r\n\r\n```html\r\n<span ng-bind=\"foo + ' ' + bar | uppercase\"></span>\r\n```\r\n\r\nIn the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene?\r\n\r\nEach `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch(\"foo + ' ' + bar | uppercase\", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.\r\n\r\nHere are the first a couple of lines of the implementation of `$watch`:\r\n\r\n```javascript\r\n$watch: function(watchExp, listener, objectEquality) {\r\n var scope = this,\r\n get = compileToFn(watchExp, 'watch'),\r\n array = scope.$$watchers,\r\n watcher = {\r\n fn: listener,\r\n last: initWatchVal,\r\n get: get,\r\n exp: watchExp,\r\n eq: !!objectEquality\r\n };\r\n//...\r\n```\r\n\r\nWe can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`\"$digest\"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`.\r\n\r\n### Controllers\r\n\r\n#### Page Controller\r\n\r\n>An object that handles a request for a specific page or action on a Web site. Martin Fowler\r\n\r\n\r\n\r\nAccording to [4](#references) the page controller:\r\n\r\n>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code\r\n\r\nSince there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.\r\n\r\nSimilarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.\r\n\r\nThe controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.\r\nHere is an example hierarchy between few controllers:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body ng-controller=\"MainCtrl\">\r\n <div ng-controller=\"ChildCtrl\">\r\n <span>{{user.name}}</span>\r\n <button ng-click=\"click()\">Click</button>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $location, User) {\r\n if (!User.isAuthenticated()) {\r\n $location.path('/unauthenticated');\r\n }\r\n}\r\n\r\nfunction ChildCtrl($scope, User) {\r\n $scope.click = function () {\r\n alert('You clicked me!');\r\n };\r\n $scope.user = User.get(0);\r\n}\r\n```\r\n\r\nThis example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.\r\n\r\nThe `ChildCtrl` is responsible for handling actions such as clicking the button with label `\"Click\"` and exposing the model to the view, by attaching it to the scope.\r\n\r\n### Others\r\n\r\n#### Module Pattern\r\n\r\nThis is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.\r\n\r\nUsing the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:\r\n\r\n```javascript\r\nvar Page = (function () {\r\n\r\n var title;\r\n\r\n function setTitle(t) {\r\n document.title = t;\r\n title = t;\r\n }\r\n\r\n function getTitle() {\r\n return title;\r\n }\r\n\r\n return {\r\n setTitle: setTitle,\r\n getTitle: getTitle\r\n };\r\n}());\r\n```\r\n\r\nIn the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.\r\n\r\nIn this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE.\r\n\r\nThe module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:\r\n\r\n```javascript\r\napp.factory('foo', function () {\r\n\r\n function privateMember() {\r\n //body...\r\n }\r\n\r\n function publicMember() {\r\n //body...\r\n privateMember();\r\n //body\r\n }\r\n\r\n return {\r\n publicMember: publicMember\r\n };\r\n});\r\n```\r\n\r\nOnce we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.\r\n\r\n### Data Mapper\r\n\r\n>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.\r\n\r\n\r\n\r\nAs the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).\r\n\r\nUsually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.\r\n\r\nFor instance, lets assume we have application in which each user has:\r\n\r\n- name\r\n- address\r\n- list of friends\r\n\r\nAnd our API has the methods:\r\n\r\n- `GET /user/:id` - returns the user's name and the address of given user\r\n- `GET /friends/:id` - returns the list of friends of given user\r\n\r\nPossible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:\r\n\r\n```javascript\r\napp.factory('User', function ($q) {\r\n\r\n function User(name, address, friends) {\r\n this.name = name;\r\n this.address = address;\r\n this.friends = friends;\r\n }\r\n\r\n User.get = function (params) {\r\n var user = $http.get('/user/' + params.id),\r\n friends = $http.get('/friends/' + params.id);\r\n $q.all([user, friends])\r\n .then(function (user, friends) {\r\n return new User(user.name, user.address, friends);\r\n });\r\n };\r\n return User;\r\n});\r\n```\r\n\r\nThis way we create pseudo-data mapper, which adapts our API according to the SPA requirements.\r\n\r\nWe can use the `User` service by:\r\n\r\n```javascript\r\nfunction MainCtrl($scope, User) {\r\n User.get({ id: 1 })\r\n .then(function (data) {\r\n $scope.user = data;\r\n });\r\n}\r\n```\r\n\r\nAnd the following partial:\r\n\r\n```html\r\n<div>\r\n <div>\r\n Name: {{user.name}}\r\n </div>\r\n <div>\r\n Address: {{user.address}}\r\n </div>\r\n <div>\r\n Friends with ids:\r\n <ul>\r\n <li ng-repeat=\"friend in user.friends\">{{friend}}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n```\r\n\r\n### Observer Pattern as an External Service\r\n\r\n##### About\r\n\r\nBelow is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.\r\n\r\n**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.\r\n\r\n##### Controller Example\r\n\r\nBelow example shows how to attach, notify and detach an event.\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout) {\r\n var vm = this;\r\n var id = 'vm1';\r\n\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n ObserverService.detachByEvent('let_me_know')\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n}\r\n```\r\nAlternative way to remove event\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout', '$scope'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout, $scope) {\r\n var vm = this;\r\n var id = 'vm1';\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n\r\n // Cleanup listeners when this controller is destroyed\r\n $scope.$on('$destroy', function handler() {\r\n ObserverService.detachByEvent('let_me_know')\r\n });\r\n}\r\n```\r\n\r\n## References\r\n\r\n1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.\r\n2. [AngularJS' documentation](https://docs.angularjs.org)\r\n3. [AngularJS' git repository](https://github.com/angular/angular.js)\r\n4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx)\r\n5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html)\r\n6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html)\r\n7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery)\r\n","google":"UA-18060688-20","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"AngularJS in Patterns","tagline":"\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.","body":"# AngularJS in Patterns\r\n\r\n<!--toc-->\r\n\r\n## Table of Contents\r\n\r\n* [Translations](#translations)\r\n* [Abstract](#abstract)\r\n* [Introduction](#introduction)\r\n* [AngularJS overview](#angularjs-overview)\r\n * [Partials](#partials)\r\n * [Controllers](#controllers)\r\n * [Scope](#scope)\r\n * [Directives](#directives)\r\n * [Filters](#filters)\r\n * [Services](#services)\r\n* [AngularJS Patterns](#angularjs-patterns)\r\n * [Services](#services-1)\r\n * [Singleton](#singleton)\r\n * [Factory Method](#factory-method)\r\n * [Decorator](#decorator)\r\n * [Facade](#facade)\r\n * [Proxy](#proxy)\r\n * [Active Record](#active-record)\r\n * [Intercepting Filters](#intercepting-filters)\r\n * [Directives](#directives-1)\r\n * [Composite](#composite)\r\n * [Interpreter](#interpreter)\r\n * [Template View](#template-view)\r\n * [Scope](#scope-1)\r\n * [Observer](#observer)\r\n * [Chain of Responsibilities](#chain-of-responsibilities)\r\n * [Command](#command)\r\n * [Controller](#controller-1)\r\n * [Page Controller](#page-controller)\r\n * [Others](#others)\r\n * [Module Pattern](#module-pattern)\r\n * [Data Mapper](#data-mapper)\r\n * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n* [References](#references)\r\n\r\n<!--endtoc-->\r\n\r\n## Translations\r\n\r\n- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter)\r\n- [Russian Translation](http://habrahabr.ru/post/250149/)\r\n- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko)\r\n\r\n## Abstract\r\n\r\nOne of the best ways to learn something new is to see how the things you already know are used in it.\r\nThis document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns.\r\nThe goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.\r\n\r\n## Introduction\r\n\r\nThe document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.\r\n\r\nThe last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.\r\n\r\n## AngularJS overview\r\n\r\nAngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA).\r\nSPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand.\r\nSince most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:\r\n\r\n- two-way data binding\r\n- dependency injection\r\n- separation of concerns\r\n- testability\r\n- abstraction\r\n\r\nThe separation of concerns is achieved by dividing each AngularJS application into separate components, such as:\r\n\r\n- partials\r\n- controllers\r\n- directives\r\n- services\r\n- filters\r\n\r\nThese components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.\r\n\r\n### Partials\r\n\r\nThe partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).\r\n\r\nInitially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.\r\n\r\n**Sample partial**\r\n\r\n```HTML\r\n<html ng-app>\r\n <!-- Body tag augmented with ngController directive -->\r\n <body ng-controller=\"MyController\">\r\n <input ng-model=\"foo\" value=\"bar\">\r\n <!-- Button tag with ng-click directive, and\r\n string expression 'buttonText'\r\n wrapped in \"{{ }}\" markup -->\r\n <button ng-click=\"changeFoo()\">{{buttonText}}</button>\r\n <script src=\"angular.js\"></script>\r\n </body>\r\n</html>\r\n```\r\n\r\nWith AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked.\r\n\r\n### Controllers\r\n\r\nThe AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*.\r\n\r\n```JavaScript\r\nfunction MyController($scope) {\r\n $scope.buttonText = 'Click me to change foo!';\r\n $scope.foo = 42;\r\n\r\n $scope.changeFoo = function () {\r\n $scope.foo += 1;\r\n alert('Foo changed');\r\n };\r\n}\r\n```\r\n\r\nFor example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.\r\n\r\n1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding.\r\n2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`.\r\n\r\nAll the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones.\r\n\r\n### Scope\r\n\r\nIn AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.\r\n\r\nAnother important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.\r\n\r\nScope inheritance is illustrated in the following example:\r\n\r\n```HTML\r\n<div ng-controller=\"BaseCtrl\">\r\n <div id=\"child\" ng-controller=\"ChildCtrl\">\r\n <button id=\"parent-method\" ng-click=\"foo()\">Parent method</button>\r\n <button ng-click=\"bar()\">Child method</button>\r\n </div>\r\n</div>\r\n```\r\n\r\n```JavaScript\r\nfunction BaseCtrl($scope) {\r\n $scope.foo = function () {\r\n alert('Base foo');\r\n };\r\n}\r\n\r\nfunction ChildCtrl($scope) {\r\n $scope.bar = function () {\r\n alert('Child bar');\r\n };\r\n}\r\n```\r\n\r\nWith `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`.\r\n\r\n### Directives\r\n\r\nIn AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations.\r\nEach directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:\r\n\r\n- template\r\n- compile function\r\n- link function\r\n- etc...\r\n\r\nBy citing the name of the directives they can be used inside the declarative partials.\r\n\r\nExample:\r\n\r\n```JavaScript\r\nmyModule.directive('alertButton', function () {\r\n return {\r\n template: '<button ng-transclude></button>',\r\n scope: {\r\n content: '@'\r\n },\r\n replace: true,\r\n restrict: 'E',\r\n transclude: true,\r\n link: function (scope, el) {\r\n el.click(function () {\r\n alert(scope.content);\r\n });\r\n }\r\n };\r\n});\r\n```\r\n\r\n```HTML\r\n<alert-button content=\"42\">Click me</alert-button>\r\n```\r\n\r\nIn the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted.\r\n\r\nSince the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.\r\n\r\n### Filters\r\n\r\nThe filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection.\r\n\r\nHere is a definition of a sample filter, which changes the given string to uppercase:\r\n\r\n```JavaScript\r\nmyModule.filter('uppercase', function () {\r\n return function (str) {\r\n return (str || '').toUpperCase();\r\n };\r\n});\r\n```\r\n\r\nInside a partial this filter could be used using the Unix's piping syntax:\r\n\r\n```HTML\r\n<div>{{ name | uppercase }}</div>\r\n```\r\n\r\nInside a controller the filter could be used as follows:\r\n\r\n```JavaScript\r\nfunction MyCtrl(uppercaseFilter) {\r\n $scope.name = uppercaseFilter('foo'); //FOO\r\n}\r\n```\r\n\r\n### Services\r\n\r\nEvery piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too \"fat\" the repetitive code should be placed inside a service.\r\n\r\n```JavaScript\r\nmyModule.service('Developer', function () {\r\n this.name = 'Foo';\r\n this.motherLanguage = 'JavaScript';\r\n this.live = function () {\r\n while (true) {\r\n this.code();\r\n }\r\n };\r\n});\r\n```\r\n\r\nThe service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).\r\n\r\n```JavaScript\r\nfunction MyCtrl(Developer) {\r\n var developer = new Developer();\r\n developer.live();\r\n}\r\n```\r\n\r\n## AngularJS Patterns\r\n\r\nIn the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.\r\n\r\nIn the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.\r\n\r\n### Services\r\n\r\n#### Singleton\r\n\r\n>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.\r\n\r\nIn the UML diagram bellow is illustrated the singleton design pattern.\r\n\r\n\r\n\r\nWhen given dependency is required by any component, AngularJS resolves it using the following algorithm:\r\n\r\n- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).\r\n- If the dependency exists AngularJS pass it as parameter to the component, which requires it.\r\n- If the dependency does not exists:\r\n - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.\r\n - AngularJS caches it inside the hash map mentioned above.\r\n - AngularJS passes it as parameter to the component, which requires it.\r\n\r\nWe can take better look at the AngularJS' source code, which implements the method `getService`:\r\n\r\n```JavaScript\r\nfunction getService(serviceName) {\r\n if (cache.hasOwnProperty(serviceName)) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));\r\n }\r\n return cache[serviceName];\r\n } else {\r\n try {\r\n path.unshift(serviceName);\r\n cache[serviceName] = INSTANTIATING;\r\n return cache[serviceName] = factory(serviceName);\r\n } catch (err) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n delete cache[serviceName];\r\n }\r\n throw err;\r\n } finally {\r\n path.shift();\r\n }\r\n }\r\n}\r\n```\r\n\r\nWe can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`).\r\n\r\nThis way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:\r\n\r\n- It improves the testability of your source code\r\n- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)\r\n\r\nFor further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered.\r\n\r\n#### Factory Method\r\n\r\n>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.\r\n\r\n\r\n\r\nLets consider the following snippet:\r\n\r\n```JavaScript\r\nmyModule.config(function ($provide) {\r\n $provide.provider('foo', function () {\r\n var baz = 42;\r\n return {\r\n //Factory method\r\n $get: function (bar) {\r\n var baz = bar.baz();\r\n return {\r\n baz: baz\r\n };\r\n }\r\n };\r\n });\r\n});\r\n\r\n```\r\n\r\nIn the code above we use the `config` callback in order to define new \"provider\". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.\r\n\r\nEach service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.\r\n\r\nWe can dig a little bit deeper in AngularJS' implementation:\r\n\r\n```JavaScript\r\n//...\r\n\r\ncreateInternalInjector(instanceCache, function(servicename) {\r\n var provider = providerInjector.get(servicename + providerSuffix);\r\n return instanceInjector.invoke(provider.$get, provider, undefined, servicename);\r\n}, strictDi));\r\n\r\n//...\r\n\r\nfunction invoke(fn, self, locals, serviceName){\r\n if (typeof locals === 'string') {\r\n serviceName = locals;\r\n locals = null;\r\n }\r\n\r\n var args = [],\r\n $inject = annotate(fn, strictDi, serviceName),\r\n length, i,\r\n key;\r\n\r\n for(i = 0, length = $inject.length; i < length; i++) {\r\n key = $inject[i];\r\n if (typeof key !== 'string') {\r\n throw $injectorMinErr('itkn',\r\n 'Incorrect injection token! Expected service name as string, got {0}', key);\r\n }\r\n args.push(\r\n locals && locals.hasOwnProperty(key)\r\n ? locals[key]\r\n : getService(key)\r\n );\r\n }\r\n if (!fn.$inject) {\r\n // this means that we must be an array.\r\n fn = fn[length];\r\n }\r\n\r\n return fn.apply(self, args);\r\n}\r\n```\r\n\r\nFrom the example above we can notice how the `$get` method is actually used:\r\n\r\n```JavaScript\r\ninstanceInjector.invoke(provider.$get, provider, undefined, servicename)\r\n```\r\n\r\nThe snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.\r\n\r\nIf we think in terms of the UML diagram above we can call the provider a \"ConcreteCreator\" and the actual component, which is being created a \"Product\".\r\n\r\nThere are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:\r\n\r\n- The most appropriate moment, when the component needs to be instantiated\r\n- Resolving all the dependencies required by the component\r\n- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)\r\n\r\n#### Decorator\r\n\r\n>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.\r\n\r\n\r\n\r\nAngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create \"wrapper\" of any service you have previously defined or used by a third-party:\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function (foo) {\r\n foo.bar();\r\n});\r\n\r\nmyModule.factory('foo', function () {\r\n return {\r\n bar: function () {\r\n console.log('I\\'m bar');\r\n },\r\n baz: function () {\r\n console.log('I\\'m baz');\r\n }\r\n };\r\n});\r\n\r\nmyModule.config(function ($provide) {\r\n $provide.decorator('foo', function ($delegate) {\r\n var barBackup = $delegate.bar;\r\n $delegate.bar = function () {\r\n console.log('Decorated');\r\n barBackup.apply($delegate, arguments);\r\n };\r\n return $delegate;\r\n });\r\n});\r\n```\r\nThe example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `\"foo\"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.\r\nWe decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.\r\n\r\nUsing this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop).\r\n\r\n#### Facade\r\n\r\n>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:\r\n\r\n>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;\r\n\r\n>2. make the library more readable, for the same reason;\r\n\r\n>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;\r\n\r\n>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).\r\n\r\n\r\n\r\nThere are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.\r\n\r\nFor example, lets take a look how we can create an `XMLHttpRequest` POST request:\r\n\r\n```JavaScript\r\nvar http = new XMLHttpRequest(),\r\n url = '/example/new',\r\n params = encodeURIComponent(data);\r\nhttp.open(\"POST\", url, true);\r\n\r\nhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\r\nhttp.setRequestHeader(\"Content-length\", params.length);\r\nhttp.setRequestHeader(\"Connection\", \"close\");\r\n\r\nhttp.onreadystatechange = function () {\r\n if(http.readyState == 4 && http.status == 200) {\r\n alert(http.responseText);\r\n }\r\n}\r\nhttp.send(params);\r\n```\r\nBut if we want to post this data using the AngularJS' `$http` service we can:\r\n\r\n```JavaScript\r\n$http({\r\n method: 'POST',\r\n url: '/example/new',\r\n data: data\r\n})\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nor we can even:\r\n\r\n```JavaScript\r\n$http.post('/someUrl', data)\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nThe second option provides pre-configured version, which creates a HTTP POST request to the given URL.\r\n\r\nEven higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections.\r\n\r\n#### Proxy\r\n\r\n>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.\r\n\r\n\r\n\r\nWe can distinguish three different types of proxy:\r\n\r\n- Virtual Proxy\r\n- Remote Proxy\r\n- Protection Proxy\r\n\r\nIn this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.\r\n\r\nIn the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = User.get({ id: 42 });\r\nconsole.log(user); //{}\r\n```\r\n\r\n`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.\r\n\r\nHow does this works with AngularJS? Well, lets consider the following snippet:\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $resource) {\r\n var User = $resource('/users/:id'),\r\n $scope.user = User.get({ id: 42 });\r\n}\r\n```\r\n\r\n```html\r\n<span ng-bind=\"user.name\"></span>\r\n```\r\nInitially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view.\r\n\r\n#### Active Record\r\n\r\n>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.\r\n\r\n\r\n\r\nAngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.\r\n\r\nAccording to the AngularJS' documentation `$resource` is:\r\n\r\n>A factory which creates a resource object that lets you interact with RESTful server-side data sources.\r\n>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.\r\n\r\nHere is how `$resource` could be used:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = new User({\r\n name: 'foo',\r\n age : 42\r\n });\r\n\r\nuser.$save();\r\n```\r\n\r\nThe call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.\r\n\r\nThis way we can use the constructor function and its static methods by:\r\n\r\n```JavaScript\r\nUser.get({ userid: userid });\r\n```\r\n\r\nThe code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)).\r\n\r\nYou can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource).\r\n\r\nSince Martin Fowler states that\r\n\r\n> responsibility of the Active Record object is to take care of the communication with the databse in order to create...\r\n\r\n`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as \"Active Record like RESTful communication\".\r\n\r\n#### Intercepting Filters\r\n\r\n>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.\r\n\r\n\r\n\r\nIn some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.\r\n\r\nIn AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`.\r\n\r\n`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error.\r\n\r\nHere is a basic example how you can add interceptors using object literal:\r\n\r\n```JavaScript\r\n$httpProvider.interceptors.push(function($q, dependency1, dependency2) {\r\n return {\r\n 'request': function(config) {\r\n // same as above\r\n },\r\n 'response': function(response) {\r\n // same as above\r\n }\r\n };\r\n});\r\n```\r\n\r\n### Directives\r\n\r\n#### Composite\r\n\r\n>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to \"compose\" objects into tree structures to represent part-whole hierarchies.\r\n\r\n\r\n\r\nAccording to the Gang of Four, MVC is nothing more than combination of:\r\n\r\n- Strategy\r\n- Composite\r\n- Observer\r\n\r\nThey state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.\r\n\r\nLets look at the following example:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body>\r\n <zippy title=\"Zippy\">\r\n Zippy!\r\n </zippy>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nmyModule.directive('zippy', function () {\r\n return {\r\n restrict: 'E',\r\n template: '<div><div class=\"header\"></div><div class=\"content\" ng-transclude></div></div>',\r\n link: function (scope, el) {\r\n el.find('.header').click(function () {\r\n el.find('.content').toggle();\r\n });\r\n }\r\n }\r\n});\r\n```\r\n\r\nThis example defines a simple directive, which is a UI component. The defined component (called \"zippy\") has header and content. Click on its header toggles the visibility of the content.\r\n\r\nFrom the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on...\r\n\r\nIn the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.\r\n\r\n#### Interpreter\r\n\r\n>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.\r\n\r\n\r\n\r\nBehind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript.\r\nThe main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:\r\n\r\n- may contain filters with UNIX like pipe syntax\r\n- don't throw any errors\r\n- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)\r\n- are evaluated in given context (the context of the current `$scope`)\r\n\r\nInside the `$parse` service are defined two main components:\r\n\r\n```JavaScript\r\n//Responsible for converting given string into tokens\r\nvar Lexer;\r\n//Responsible for parsing the tokens and evaluating the expression\r\nvar Parser;\r\n```\r\n\r\nOnce given expression have been tokenized it is cached internally, because of performance concerns.\r\n\r\nThe terminal expressions in the AngularJS DSL are defined as follows:\r\n\r\n```JavaScript\r\nvar OPERATORS = {\r\n /* jshint bitwise : false */\r\n 'null':function(){return null;},\r\n 'true':function(){return true;},\r\n 'false':function(){return false;},\r\n undefined:noop,\r\n '+':function(self, locals, a,b){\r\n //...\r\n },\r\n '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},\r\n '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},\r\n '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},\r\n '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},\r\n '=':noop,\r\n '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},\r\n '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},\r\n '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},\r\n '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},\r\n '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},\r\n '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},\r\n '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},\r\n '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},\r\n '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},\r\n '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},\r\n '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},\r\n '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},\r\n '!':function(self, locals, a){return !a(self, locals);}\r\n};\r\n```\r\n\r\nWe can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface.\r\n\r\nEach `Client` interprets given AngularJS expression in a specific context - specific scope.\r\n\r\nFew sample AngularJS expressions are:\r\n\r\n```JavaScript\r\n// toUpperCase filter is applied to the result of the expression\r\n// (foo) ? bar : baz\r\n(foo) ? bar : baz | toUpperCase\r\n```\r\n\r\n#### Template View\r\n\r\n> Renders information into HTML by embedding markers in an HTML page.\r\n\r\n\r\n\r\nThe dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.\r\n\r\nTemplates are very commonly used especially in the back-end.\r\nFor example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.\r\n\r\nFor JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript.\r\n\r\nFor example:\r\n\r\n```html\r\n<script type=\"template/mustache\">\r\n <h2>Names</h2>\r\n {{#names}}\r\n <strong>{{name}}</strong>\r\n {{/names}}\r\n</script>\r\n```\r\n\r\nThe template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.\r\n\r\nFor example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get:\r\n\r\n```html\r\n<h2>Names</h2>\r\n <strong>foo</strong>\r\n <strong>bar</strong>\r\n <strong>baz</strong>\r\n```\r\n\r\nAngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are.\r\nWhat AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.\r\n\r\nFor example:\r\n\r\n```html\r\n<ul ng-repeat=\"name in names\">\r\n <li>{{name}}</li>\r\n</ul>\r\n```\r\n\r\nin the context of the scope:\r\n\r\n```javascript\r\n$scope.names = ['foo', 'bar', 'baz'];\r\n```\r\n\r\nwill produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead.\r\n\r\n\r\n### Scope\r\n\r\n#### Observer\r\n\r\n>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.\r\n\r\n\r\n\r\nThere are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.\r\n\r\nEach AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$on('event-name', function handler() {\r\n //body\r\n });\r\n}\r\n```\r\n\r\nIn this way the current scope \"subscribes\" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.\r\n\r\nThe methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.\r\nFor example:\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$emit('event-name', { foo: 'bar' });\r\n}\r\n```\r\n\r\nThe scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.\r\n\r\nAnalogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.\r\nEach scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).\r\n\r\nIn the JavaScript community this pattern is better known as publish/subscribe.\r\n\r\nFor a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n\r\n#### Chain of Responsibilities\r\n\r\n>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.\r\n\r\n\r\n\r\nAs stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are \"isolated\", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.\r\n\r\nWhen `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:\r\n\r\n- Handle the event and pass it to the next scope in the chain\r\n- Handle the event and stop its propagation\r\n- Pass the event to the next scope in the chain without handling it\r\n- Stop the event propagation without handling it\r\n\r\nIn the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `\"foo received\"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback.\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function ($scope) {\r\n $scope.$on('foo', function () {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ParentCtrl', function ($scope) {\r\n $scope.$on('foo', function (e) {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ChildCtrl', function ($scope) {\r\n $scope.$emit('foo');\r\n});\r\n```\r\n\r\nThe different handlers from the UML diagram above are the different scopes, injected to the controllers.\r\n\r\n#### Command\r\n\r\n>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.\r\n\r\n\r\n\r\nBefore continuing with the application of the command pattern lets describe how AngularJS implements data binding.\r\n\r\nWhen we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can:\r\n\r\n```html\r\n<span ng-bind=\"foo\"></span>\r\n```\r\n\r\nNow each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:\r\n\r\n```html\r\n<span ng-bind=\"foo + ' ' + bar | uppercase\"></span>\r\n```\r\n\r\nIn the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene?\r\n\r\nEach `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch(\"foo + ' ' + bar | uppercase\", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.\r\n\r\nHere are the first a couple of lines of the implementation of `$watch`:\r\n\r\n```javascript\r\n$watch: function(watchExp, listener, objectEquality) {\r\n var scope = this,\r\n get = compileToFn(watchExp, 'watch'),\r\n array = scope.$$watchers,\r\n watcher = {\r\n fn: listener,\r\n last: initWatchVal,\r\n get: get,\r\n exp: watchExp,\r\n eq: !!objectEquality\r\n };\r\n//...\r\n```\r\n\r\nWe can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`\"$digest\"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`.\r\n\r\n### Controllers\r\n\r\n#### Page Controller\r\n\r\n>An object that handles a request for a specific page or action on a Web site. Martin Fowler\r\n\r\n\r\n\r\nAccording to [4](#references) the page controller:\r\n\r\n>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code\r\n\r\nSince there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.\r\n\r\nSimilarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.\r\n\r\nThe controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.\r\nHere is an example hierarchy between few controllers:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body ng-controller=\"MainCtrl\">\r\n <div ng-controller=\"ChildCtrl\">\r\n <span>{{user.name}}</span>\r\n <button ng-click=\"click()\">Click</button>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $location, User) {\r\n if (!User.isAuthenticated()) {\r\n $location.path('/unauthenticated');\r\n }\r\n}\r\n\r\nfunction ChildCtrl($scope, User) {\r\n $scope.click = function () {\r\n alert('You clicked me!');\r\n };\r\n $scope.user = User.get(0);\r\n}\r\n```\r\n\r\nThis example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.\r\n\r\nThe `ChildCtrl` is responsible for handling actions such as clicking the button with label `\"Click\"` and exposing the model to the view, by attaching it to the scope.\r\n\r\n### Others\r\n\r\n#### Module Pattern\r\n\r\nThis is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.\r\n\r\nUsing the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:\r\n\r\n```javascript\r\nvar Page = (function () {\r\n\r\n var title;\r\n\r\n function setTitle(t) {\r\n document.title = t;\r\n title = t;\r\n }\r\n\r\n function getTitle() {\r\n return title;\r\n }\r\n\r\n return {\r\n setTitle: setTitle,\r\n getTitle: getTitle\r\n };\r\n}());\r\n```\r\n\r\nIn the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.\r\n\r\nIn this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE.\r\n\r\nThe module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:\r\n\r\n```javascript\r\napp.factory('foo', function () {\r\n\r\n function privateMember() {\r\n //body...\r\n }\r\n\r\n function publicMember() {\r\n //body...\r\n privateMember();\r\n //body\r\n }\r\n\r\n return {\r\n publicMember: publicMember\r\n };\r\n});\r\n```\r\n\r\nOnce we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.\r\n\r\n#### Data Mapper\r\n\r\n>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.\r\n\r\n\r\n\r\nAs the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).\r\n\r\nUsually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.\r\n\r\nFor instance, lets assume we have application in which each user has:\r\n\r\n- name\r\n- address\r\n- list of friends\r\n\r\nAnd our API has the methods:\r\n\r\n- `GET /user/:id` - returns the user's name and the address of given user\r\n- `GET /friends/:id` - returns the list of friends of given user\r\n\r\nPossible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:\r\n\r\n```javascript\r\napp.factory('User', function ($q) {\r\n\r\n function User(name, address, friends) {\r\n this.name = name;\r\n this.address = address;\r\n this.friends = friends;\r\n }\r\n\r\n User.get = function (params) {\r\n var user = $http.get('/user/' + params.id),\r\n friends = $http.get('/friends/' + params.id);\r\n $q.all([user, friends])\r\n .then(function (user, friends) {\r\n return new User(user.name, user.address, friends);\r\n });\r\n };\r\n return User;\r\n});\r\n```\r\n\r\nThis way we create pseudo-data mapper, which adapts our API according to the SPA requirements.\r\n\r\nWe can use the `User` service by:\r\n\r\n```javascript\r\nfunction MainCtrl($scope, User) {\r\n User.get({ id: 1 })\r\n .then(function (data) {\r\n $scope.user = data;\r\n });\r\n}\r\n```\r\n\r\nAnd the following partial:\r\n\r\n```html\r\n<div>\r\n <div>\r\n Name: {{user.name}}\r\n </div>\r\n <div>\r\n Address: {{user.address}}\r\n </div>\r\n <div>\r\n Friends with ids:\r\n <ul>\r\n <li ng-repeat=\"friend in user.friends\">{{friend}}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n```\r\n\r\n#### Observer Pattern as an External Service\r\n\r\n##### About\r\n\r\nBelow is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.\r\n\r\n**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.\r\n\r\n##### Controller Example\r\n\r\nBelow example shows how to attach, notify and detach an event.\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout) {\r\n var vm = this;\r\n var id = 'vm1';\r\n\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n ObserverService.detachByEvent('let_me_know')\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n}\r\n```\r\nAlternative way to remove event\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout', '$scope'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout, $scope) {\r\n var vm = this;\r\n var id = 'vm1';\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n\r\n // Cleanup listeners when this controller is destroyed\r\n $scope.$on('$destroy', function handler() {\r\n ObserverService.detachByEvent('let_me_know')\r\n });\r\n}\r\n```\r\n\r\n## References\r\n\r\n1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.\r\n2. [AngularJS' documentation](https://docs.angularjs.org)\r\n3. [AngularJS' git repository](https://github.com/angular/angular.js)\r\n4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx)\r\n5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html)\r\n6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html)\r\n7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery)\r\n","google":"UA-18060688-20","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 9f31592c76fa1f59898fee0485e01a1b128dbb55 Mon Sep 17 00:00:00 2001 From: Minko Gechev <mgechev@gmail.com> Date: Wed, 30 Sep 2015 14:32:46 +0300 Subject: [PATCH 16/19] Create gh-pages branch via GitHub --- index.html | 19 +++++++++++-------- params.json | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 848aaa4..de9411d 100644 --- a/index.html +++ b/index.html @@ -112,6 +112,9 @@ <h2> <li> <a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md">French Translation</a> by <a href="https://github.com/manekinekko">manekinekko</a> </li> +<li> +<a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-zh-cn.md">Chinese Translation</a> by <a href="https://github.com/carlosliu">carlosliu</a> +</li> </ul> <h2> @@ -495,10 +498,10 @@ <h4> myModule.factory(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { <span class="pl-k">return</span> { <span class="pl-en">bar</span><span class="pl-k">:</span> <span class="pl-k">function</span> () { - <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m bar<span class="pl-pds">'</span></span>); + <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m bar<span class="pl-pds">'</span></span>); }, <span class="pl-en">baz</span><span class="pl-k">:</span> <span class="pl-k">function</span> () { - <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m baz<span class="pl-pds">'</span></span>); + <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m baz<span class="pl-pds">'</span></span>); } }; }); @@ -507,7 +510,7 @@ <h4> $provide.decorator(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$delegate</span>) { <span class="pl-k">var</span> barBackup <span class="pl-k">=</span> $delegate.bar; <span class="pl-c1">$delegate</span>.<span class="pl-en">bar</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>Decorated<span class="pl-pds">'</span></span>); + <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>Decorated<span class="pl-pds">'</span></span>); barBackup.<span class="pl-c1">apply</span>($delegate, arguments); }; <span class="pl-k">return</span> $delegate; @@ -600,7 +603,7 @@ <h4> <div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $resource(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), user <span class="pl-k">=</span> User.get({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); -<span class="pl-en">console</span><span class="pl-c1">.log</span>(user); <span class="pl-c">//{}</span></pre></div> +<span class="pl-en">console</span>.<span class="pl-c1">log</span>(user); <span class="pl-c">//{}</span></pre></div> <p><code>console.log</code> would outputs an empty object. Since the AJAX request, which happens behind the scene, when <code>User.get</code> is invoked, is asynchronous, we don't have the actual user when <code>console.log</code> is called. Just after <code>User.get</code> makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.</p> @@ -924,13 +927,13 @@ <h4> <div class="highlight highlight-source-js"><pre>myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); + <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); }); }); myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>ParentCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">e</span>) { - <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); + <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); }); }); @@ -1193,7 +1196,7 @@ <h5> ObserverService.attach(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) <span class="pl-k">function</span> <span class="pl-en">callbackFunction</span>(<span class="pl-smi">params</span>){ - <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); + <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); ObserverService.detachByEvent(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) } @@ -1214,7 +1217,7 @@ <h5> ObserverService.attach(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) <span class="pl-k">function</span> <span class="pl-en">callbackFunction</span>(<span class="pl-smi">params</span>){ - <span class="pl-en">console</span><span class="pl-c1">.log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); + <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); } $timeout(<span class="pl-k">function</span>(){ diff --git a/params.json b/params.json index f0d2456..a888b12 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"AngularJS in Patterns","tagline":"\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.","body":"# AngularJS in Patterns\r\n\r\n<!--toc-->\r\n\r\n## Table of Contents\r\n\r\n* [Translations](#translations)\r\n* [Abstract](#abstract)\r\n* [Introduction](#introduction)\r\n* [AngularJS overview](#angularjs-overview)\r\n * [Partials](#partials)\r\n * [Controllers](#controllers)\r\n * [Scope](#scope)\r\n * [Directives](#directives)\r\n * [Filters](#filters)\r\n * [Services](#services)\r\n* [AngularJS Patterns](#angularjs-patterns)\r\n * [Services](#services-1)\r\n * [Singleton](#singleton)\r\n * [Factory Method](#factory-method)\r\n * [Decorator](#decorator)\r\n * [Facade](#facade)\r\n * [Proxy](#proxy)\r\n * [Active Record](#active-record)\r\n * [Intercepting Filters](#intercepting-filters)\r\n * [Directives](#directives-1)\r\n * [Composite](#composite)\r\n * [Interpreter](#interpreter)\r\n * [Template View](#template-view)\r\n * [Scope](#scope-1)\r\n * [Observer](#observer)\r\n * [Chain of Responsibilities](#chain-of-responsibilities)\r\n * [Command](#command)\r\n * [Controller](#controller-1)\r\n * [Page Controller](#page-controller)\r\n * [Others](#others)\r\n * [Module Pattern](#module-pattern)\r\n * [Data Mapper](#data-mapper)\r\n * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n* [References](#references)\r\n\r\n<!--endtoc-->\r\n\r\n## Translations\r\n\r\n- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter)\r\n- [Russian Translation](http://habrahabr.ru/post/250149/)\r\n- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko)\r\n\r\n## Abstract\r\n\r\nOne of the best ways to learn something new is to see how the things you already know are used in it.\r\nThis document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns.\r\nThe goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.\r\n\r\n## Introduction\r\n\r\nThe document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.\r\n\r\nThe last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.\r\n\r\n## AngularJS overview\r\n\r\nAngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA).\r\nSPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand.\r\nSince most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:\r\n\r\n- two-way data binding\r\n- dependency injection\r\n- separation of concerns\r\n- testability\r\n- abstraction\r\n\r\nThe separation of concerns is achieved by dividing each AngularJS application into separate components, such as:\r\n\r\n- partials\r\n- controllers\r\n- directives\r\n- services\r\n- filters\r\n\r\nThese components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.\r\n\r\n### Partials\r\n\r\nThe partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).\r\n\r\nInitially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.\r\n\r\n**Sample partial**\r\n\r\n```HTML\r\n<html ng-app>\r\n <!-- Body tag augmented with ngController directive -->\r\n <body ng-controller=\"MyController\">\r\n <input ng-model=\"foo\" value=\"bar\">\r\n <!-- Button tag with ng-click directive, and\r\n string expression 'buttonText'\r\n wrapped in \"{{ }}\" markup -->\r\n <button ng-click=\"changeFoo()\">{{buttonText}}</button>\r\n <script src=\"angular.js\"></script>\r\n </body>\r\n</html>\r\n```\r\n\r\nWith AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked.\r\n\r\n### Controllers\r\n\r\nThe AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*.\r\n\r\n```JavaScript\r\nfunction MyController($scope) {\r\n $scope.buttonText = 'Click me to change foo!';\r\n $scope.foo = 42;\r\n\r\n $scope.changeFoo = function () {\r\n $scope.foo += 1;\r\n alert('Foo changed');\r\n };\r\n}\r\n```\r\n\r\nFor example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.\r\n\r\n1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding.\r\n2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`.\r\n\r\nAll the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones.\r\n\r\n### Scope\r\n\r\nIn AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.\r\n\r\nAnother important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.\r\n\r\nScope inheritance is illustrated in the following example:\r\n\r\n```HTML\r\n<div ng-controller=\"BaseCtrl\">\r\n <div id=\"child\" ng-controller=\"ChildCtrl\">\r\n <button id=\"parent-method\" ng-click=\"foo()\">Parent method</button>\r\n <button ng-click=\"bar()\">Child method</button>\r\n </div>\r\n</div>\r\n```\r\n\r\n```JavaScript\r\nfunction BaseCtrl($scope) {\r\n $scope.foo = function () {\r\n alert('Base foo');\r\n };\r\n}\r\n\r\nfunction ChildCtrl($scope) {\r\n $scope.bar = function () {\r\n alert('Child bar');\r\n };\r\n}\r\n```\r\n\r\nWith `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`.\r\n\r\n### Directives\r\n\r\nIn AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations.\r\nEach directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:\r\n\r\n- template\r\n- compile function\r\n- link function\r\n- etc...\r\n\r\nBy citing the name of the directives they can be used inside the declarative partials.\r\n\r\nExample:\r\n\r\n```JavaScript\r\nmyModule.directive('alertButton', function () {\r\n return {\r\n template: '<button ng-transclude></button>',\r\n scope: {\r\n content: '@'\r\n },\r\n replace: true,\r\n restrict: 'E',\r\n transclude: true,\r\n link: function (scope, el) {\r\n el.click(function () {\r\n alert(scope.content);\r\n });\r\n }\r\n };\r\n});\r\n```\r\n\r\n```HTML\r\n<alert-button content=\"42\">Click me</alert-button>\r\n```\r\n\r\nIn the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted.\r\n\r\nSince the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.\r\n\r\n### Filters\r\n\r\nThe filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection.\r\n\r\nHere is a definition of a sample filter, which changes the given string to uppercase:\r\n\r\n```JavaScript\r\nmyModule.filter('uppercase', function () {\r\n return function (str) {\r\n return (str || '').toUpperCase();\r\n };\r\n});\r\n```\r\n\r\nInside a partial this filter could be used using the Unix's piping syntax:\r\n\r\n```HTML\r\n<div>{{ name | uppercase }}</div>\r\n```\r\n\r\nInside a controller the filter could be used as follows:\r\n\r\n```JavaScript\r\nfunction MyCtrl(uppercaseFilter) {\r\n $scope.name = uppercaseFilter('foo'); //FOO\r\n}\r\n```\r\n\r\n### Services\r\n\r\nEvery piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too \"fat\" the repetitive code should be placed inside a service.\r\n\r\n```JavaScript\r\nmyModule.service('Developer', function () {\r\n this.name = 'Foo';\r\n this.motherLanguage = 'JavaScript';\r\n this.live = function () {\r\n while (true) {\r\n this.code();\r\n }\r\n };\r\n});\r\n```\r\n\r\nThe service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).\r\n\r\n```JavaScript\r\nfunction MyCtrl(Developer) {\r\n var developer = new Developer();\r\n developer.live();\r\n}\r\n```\r\n\r\n## AngularJS Patterns\r\n\r\nIn the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.\r\n\r\nIn the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.\r\n\r\n### Services\r\n\r\n#### Singleton\r\n\r\n>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.\r\n\r\nIn the UML diagram bellow is illustrated the singleton design pattern.\r\n\r\n\r\n\r\nWhen given dependency is required by any component, AngularJS resolves it using the following algorithm:\r\n\r\n- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).\r\n- If the dependency exists AngularJS pass it as parameter to the component, which requires it.\r\n- If the dependency does not exists:\r\n - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.\r\n - AngularJS caches it inside the hash map mentioned above.\r\n - AngularJS passes it as parameter to the component, which requires it.\r\n\r\nWe can take better look at the AngularJS' source code, which implements the method `getService`:\r\n\r\n```JavaScript\r\nfunction getService(serviceName) {\r\n if (cache.hasOwnProperty(serviceName)) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));\r\n }\r\n return cache[serviceName];\r\n } else {\r\n try {\r\n path.unshift(serviceName);\r\n cache[serviceName] = INSTANTIATING;\r\n return cache[serviceName] = factory(serviceName);\r\n } catch (err) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n delete cache[serviceName];\r\n }\r\n throw err;\r\n } finally {\r\n path.shift();\r\n }\r\n }\r\n}\r\n```\r\n\r\nWe can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`).\r\n\r\nThis way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:\r\n\r\n- It improves the testability of your source code\r\n- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)\r\n\r\nFor further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered.\r\n\r\n#### Factory Method\r\n\r\n>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.\r\n\r\n\r\n\r\nLets consider the following snippet:\r\n\r\n```JavaScript\r\nmyModule.config(function ($provide) {\r\n $provide.provider('foo', function () {\r\n var baz = 42;\r\n return {\r\n //Factory method\r\n $get: function (bar) {\r\n var baz = bar.baz();\r\n return {\r\n baz: baz\r\n };\r\n }\r\n };\r\n });\r\n});\r\n\r\n```\r\n\r\nIn the code above we use the `config` callback in order to define new \"provider\". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.\r\n\r\nEach service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.\r\n\r\nWe can dig a little bit deeper in AngularJS' implementation:\r\n\r\n```JavaScript\r\n//...\r\n\r\ncreateInternalInjector(instanceCache, function(servicename) {\r\n var provider = providerInjector.get(servicename + providerSuffix);\r\n return instanceInjector.invoke(provider.$get, provider, undefined, servicename);\r\n}, strictDi));\r\n\r\n//...\r\n\r\nfunction invoke(fn, self, locals, serviceName){\r\n if (typeof locals === 'string') {\r\n serviceName = locals;\r\n locals = null;\r\n }\r\n\r\n var args = [],\r\n $inject = annotate(fn, strictDi, serviceName),\r\n length, i,\r\n key;\r\n\r\n for(i = 0, length = $inject.length; i < length; i++) {\r\n key = $inject[i];\r\n if (typeof key !== 'string') {\r\n throw $injectorMinErr('itkn',\r\n 'Incorrect injection token! Expected service name as string, got {0}', key);\r\n }\r\n args.push(\r\n locals && locals.hasOwnProperty(key)\r\n ? locals[key]\r\n : getService(key)\r\n );\r\n }\r\n if (!fn.$inject) {\r\n // this means that we must be an array.\r\n fn = fn[length];\r\n }\r\n\r\n return fn.apply(self, args);\r\n}\r\n```\r\n\r\nFrom the example above we can notice how the `$get` method is actually used:\r\n\r\n```JavaScript\r\ninstanceInjector.invoke(provider.$get, provider, undefined, servicename)\r\n```\r\n\r\nThe snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.\r\n\r\nIf we think in terms of the UML diagram above we can call the provider a \"ConcreteCreator\" and the actual component, which is being created a \"Product\".\r\n\r\nThere are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:\r\n\r\n- The most appropriate moment, when the component needs to be instantiated\r\n- Resolving all the dependencies required by the component\r\n- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)\r\n\r\n#### Decorator\r\n\r\n>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.\r\n\r\n\r\n\r\nAngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create \"wrapper\" of any service you have previously defined or used by a third-party:\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function (foo) {\r\n foo.bar();\r\n});\r\n\r\nmyModule.factory('foo', function () {\r\n return {\r\n bar: function () {\r\n console.log('I\\'m bar');\r\n },\r\n baz: function () {\r\n console.log('I\\'m baz');\r\n }\r\n };\r\n});\r\n\r\nmyModule.config(function ($provide) {\r\n $provide.decorator('foo', function ($delegate) {\r\n var barBackup = $delegate.bar;\r\n $delegate.bar = function () {\r\n console.log('Decorated');\r\n barBackup.apply($delegate, arguments);\r\n };\r\n return $delegate;\r\n });\r\n});\r\n```\r\nThe example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `\"foo\"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.\r\nWe decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.\r\n\r\nUsing this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop).\r\n\r\n#### Facade\r\n\r\n>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:\r\n\r\n>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;\r\n\r\n>2. make the library more readable, for the same reason;\r\n\r\n>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;\r\n\r\n>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).\r\n\r\n\r\n\r\nThere are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.\r\n\r\nFor example, lets take a look how we can create an `XMLHttpRequest` POST request:\r\n\r\n```JavaScript\r\nvar http = new XMLHttpRequest(),\r\n url = '/example/new',\r\n params = encodeURIComponent(data);\r\nhttp.open(\"POST\", url, true);\r\n\r\nhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\r\nhttp.setRequestHeader(\"Content-length\", params.length);\r\nhttp.setRequestHeader(\"Connection\", \"close\");\r\n\r\nhttp.onreadystatechange = function () {\r\n if(http.readyState == 4 && http.status == 200) {\r\n alert(http.responseText);\r\n }\r\n}\r\nhttp.send(params);\r\n```\r\nBut if we want to post this data using the AngularJS' `$http` service we can:\r\n\r\n```JavaScript\r\n$http({\r\n method: 'POST',\r\n url: '/example/new',\r\n data: data\r\n})\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nor we can even:\r\n\r\n```JavaScript\r\n$http.post('/someUrl', data)\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nThe second option provides pre-configured version, which creates a HTTP POST request to the given URL.\r\n\r\nEven higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections.\r\n\r\n#### Proxy\r\n\r\n>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.\r\n\r\n\r\n\r\nWe can distinguish three different types of proxy:\r\n\r\n- Virtual Proxy\r\n- Remote Proxy\r\n- Protection Proxy\r\n\r\nIn this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.\r\n\r\nIn the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = User.get({ id: 42 });\r\nconsole.log(user); //{}\r\n```\r\n\r\n`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.\r\n\r\nHow does this works with AngularJS? Well, lets consider the following snippet:\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $resource) {\r\n var User = $resource('/users/:id'),\r\n $scope.user = User.get({ id: 42 });\r\n}\r\n```\r\n\r\n```html\r\n<span ng-bind=\"user.name\"></span>\r\n```\r\nInitially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view.\r\n\r\n#### Active Record\r\n\r\n>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.\r\n\r\n\r\n\r\nAngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.\r\n\r\nAccording to the AngularJS' documentation `$resource` is:\r\n\r\n>A factory which creates a resource object that lets you interact with RESTful server-side data sources.\r\n>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.\r\n\r\nHere is how `$resource` could be used:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = new User({\r\n name: 'foo',\r\n age : 42\r\n });\r\n\r\nuser.$save();\r\n```\r\n\r\nThe call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.\r\n\r\nThis way we can use the constructor function and its static methods by:\r\n\r\n```JavaScript\r\nUser.get({ userid: userid });\r\n```\r\n\r\nThe code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)).\r\n\r\nYou can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource).\r\n\r\nSince Martin Fowler states that\r\n\r\n> responsibility of the Active Record object is to take care of the communication with the databse in order to create...\r\n\r\n`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as \"Active Record like RESTful communication\".\r\n\r\n#### Intercepting Filters\r\n\r\n>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.\r\n\r\n\r\n\r\nIn some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.\r\n\r\nIn AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`.\r\n\r\n`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error.\r\n\r\nHere is a basic example how you can add interceptors using object literal:\r\n\r\n```JavaScript\r\n$httpProvider.interceptors.push(function($q, dependency1, dependency2) {\r\n return {\r\n 'request': function(config) {\r\n // same as above\r\n },\r\n 'response': function(response) {\r\n // same as above\r\n }\r\n };\r\n});\r\n```\r\n\r\n### Directives\r\n\r\n#### Composite\r\n\r\n>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to \"compose\" objects into tree structures to represent part-whole hierarchies.\r\n\r\n\r\n\r\nAccording to the Gang of Four, MVC is nothing more than combination of:\r\n\r\n- Strategy\r\n- Composite\r\n- Observer\r\n\r\nThey state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.\r\n\r\nLets look at the following example:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body>\r\n <zippy title=\"Zippy\">\r\n Zippy!\r\n </zippy>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nmyModule.directive('zippy', function () {\r\n return {\r\n restrict: 'E',\r\n template: '<div><div class=\"header\"></div><div class=\"content\" ng-transclude></div></div>',\r\n link: function (scope, el) {\r\n el.find('.header').click(function () {\r\n el.find('.content').toggle();\r\n });\r\n }\r\n }\r\n});\r\n```\r\n\r\nThis example defines a simple directive, which is a UI component. The defined component (called \"zippy\") has header and content. Click on its header toggles the visibility of the content.\r\n\r\nFrom the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on...\r\n\r\nIn the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.\r\n\r\n#### Interpreter\r\n\r\n>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.\r\n\r\n\r\n\r\nBehind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript.\r\nThe main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:\r\n\r\n- may contain filters with UNIX like pipe syntax\r\n- don't throw any errors\r\n- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)\r\n- are evaluated in given context (the context of the current `$scope`)\r\n\r\nInside the `$parse` service are defined two main components:\r\n\r\n```JavaScript\r\n//Responsible for converting given string into tokens\r\nvar Lexer;\r\n//Responsible for parsing the tokens and evaluating the expression\r\nvar Parser;\r\n```\r\n\r\nOnce given expression have been tokenized it is cached internally, because of performance concerns.\r\n\r\nThe terminal expressions in the AngularJS DSL are defined as follows:\r\n\r\n```JavaScript\r\nvar OPERATORS = {\r\n /* jshint bitwise : false */\r\n 'null':function(){return null;},\r\n 'true':function(){return true;},\r\n 'false':function(){return false;},\r\n undefined:noop,\r\n '+':function(self, locals, a,b){\r\n //...\r\n },\r\n '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},\r\n '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},\r\n '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},\r\n '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},\r\n '=':noop,\r\n '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},\r\n '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},\r\n '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},\r\n '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},\r\n '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},\r\n '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},\r\n '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},\r\n '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},\r\n '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},\r\n '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},\r\n '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},\r\n '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},\r\n '!':function(self, locals, a){return !a(self, locals);}\r\n};\r\n```\r\n\r\nWe can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface.\r\n\r\nEach `Client` interprets given AngularJS expression in a specific context - specific scope.\r\n\r\nFew sample AngularJS expressions are:\r\n\r\n```JavaScript\r\n// toUpperCase filter is applied to the result of the expression\r\n// (foo) ? bar : baz\r\n(foo) ? bar : baz | toUpperCase\r\n```\r\n\r\n#### Template View\r\n\r\n> Renders information into HTML by embedding markers in an HTML page.\r\n\r\n\r\n\r\nThe dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.\r\n\r\nTemplates are very commonly used especially in the back-end.\r\nFor example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.\r\n\r\nFor JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript.\r\n\r\nFor example:\r\n\r\n```html\r\n<script type=\"template/mustache\">\r\n <h2>Names</h2>\r\n {{#names}}\r\n <strong>{{name}}</strong>\r\n {{/names}}\r\n</script>\r\n```\r\n\r\nThe template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.\r\n\r\nFor example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get:\r\n\r\n```html\r\n<h2>Names</h2>\r\n <strong>foo</strong>\r\n <strong>bar</strong>\r\n <strong>baz</strong>\r\n```\r\n\r\nAngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are.\r\nWhat AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.\r\n\r\nFor example:\r\n\r\n```html\r\n<ul ng-repeat=\"name in names\">\r\n <li>{{name}}</li>\r\n</ul>\r\n```\r\n\r\nin the context of the scope:\r\n\r\n```javascript\r\n$scope.names = ['foo', 'bar', 'baz'];\r\n```\r\n\r\nwill produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead.\r\n\r\n\r\n### Scope\r\n\r\n#### Observer\r\n\r\n>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.\r\n\r\n\r\n\r\nThere are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.\r\n\r\nEach AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$on('event-name', function handler() {\r\n //body\r\n });\r\n}\r\n```\r\n\r\nIn this way the current scope \"subscribes\" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.\r\n\r\nThe methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.\r\nFor example:\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$emit('event-name', { foo: 'bar' });\r\n}\r\n```\r\n\r\nThe scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.\r\n\r\nAnalogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.\r\nEach scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).\r\n\r\nIn the JavaScript community this pattern is better known as publish/subscribe.\r\n\r\nFor a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n\r\n#### Chain of Responsibilities\r\n\r\n>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.\r\n\r\n\r\n\r\nAs stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are \"isolated\", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.\r\n\r\nWhen `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:\r\n\r\n- Handle the event and pass it to the next scope in the chain\r\n- Handle the event and stop its propagation\r\n- Pass the event to the next scope in the chain without handling it\r\n- Stop the event propagation without handling it\r\n\r\nIn the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `\"foo received\"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback.\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function ($scope) {\r\n $scope.$on('foo', function () {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ParentCtrl', function ($scope) {\r\n $scope.$on('foo', function (e) {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ChildCtrl', function ($scope) {\r\n $scope.$emit('foo');\r\n});\r\n```\r\n\r\nThe different handlers from the UML diagram above are the different scopes, injected to the controllers.\r\n\r\n#### Command\r\n\r\n>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.\r\n\r\n\r\n\r\nBefore continuing with the application of the command pattern lets describe how AngularJS implements data binding.\r\n\r\nWhen we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can:\r\n\r\n```html\r\n<span ng-bind=\"foo\"></span>\r\n```\r\n\r\nNow each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:\r\n\r\n```html\r\n<span ng-bind=\"foo + ' ' + bar | uppercase\"></span>\r\n```\r\n\r\nIn the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene?\r\n\r\nEach `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch(\"foo + ' ' + bar | uppercase\", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.\r\n\r\nHere are the first a couple of lines of the implementation of `$watch`:\r\n\r\n```javascript\r\n$watch: function(watchExp, listener, objectEquality) {\r\n var scope = this,\r\n get = compileToFn(watchExp, 'watch'),\r\n array = scope.$$watchers,\r\n watcher = {\r\n fn: listener,\r\n last: initWatchVal,\r\n get: get,\r\n exp: watchExp,\r\n eq: !!objectEquality\r\n };\r\n//...\r\n```\r\n\r\nWe can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`\"$digest\"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`.\r\n\r\n### Controllers\r\n\r\n#### Page Controller\r\n\r\n>An object that handles a request for a specific page or action on a Web site. Martin Fowler\r\n\r\n\r\n\r\nAccording to [4](#references) the page controller:\r\n\r\n>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code\r\n\r\nSince there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.\r\n\r\nSimilarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.\r\n\r\nThe controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.\r\nHere is an example hierarchy between few controllers:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body ng-controller=\"MainCtrl\">\r\n <div ng-controller=\"ChildCtrl\">\r\n <span>{{user.name}}</span>\r\n <button ng-click=\"click()\">Click</button>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $location, User) {\r\n if (!User.isAuthenticated()) {\r\n $location.path('/unauthenticated');\r\n }\r\n}\r\n\r\nfunction ChildCtrl($scope, User) {\r\n $scope.click = function () {\r\n alert('You clicked me!');\r\n };\r\n $scope.user = User.get(0);\r\n}\r\n```\r\n\r\nThis example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.\r\n\r\nThe `ChildCtrl` is responsible for handling actions such as clicking the button with label `\"Click\"` and exposing the model to the view, by attaching it to the scope.\r\n\r\n### Others\r\n\r\n#### Module Pattern\r\n\r\nThis is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.\r\n\r\nUsing the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:\r\n\r\n```javascript\r\nvar Page = (function () {\r\n\r\n var title;\r\n\r\n function setTitle(t) {\r\n document.title = t;\r\n title = t;\r\n }\r\n\r\n function getTitle() {\r\n return title;\r\n }\r\n\r\n return {\r\n setTitle: setTitle,\r\n getTitle: getTitle\r\n };\r\n}());\r\n```\r\n\r\nIn the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.\r\n\r\nIn this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE.\r\n\r\nThe module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:\r\n\r\n```javascript\r\napp.factory('foo', function () {\r\n\r\n function privateMember() {\r\n //body...\r\n }\r\n\r\n function publicMember() {\r\n //body...\r\n privateMember();\r\n //body\r\n }\r\n\r\n return {\r\n publicMember: publicMember\r\n };\r\n});\r\n```\r\n\r\nOnce we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.\r\n\r\n#### Data Mapper\r\n\r\n>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.\r\n\r\n\r\n\r\nAs the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).\r\n\r\nUsually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.\r\n\r\nFor instance, lets assume we have application in which each user has:\r\n\r\n- name\r\n- address\r\n- list of friends\r\n\r\nAnd our API has the methods:\r\n\r\n- `GET /user/:id` - returns the user's name and the address of given user\r\n- `GET /friends/:id` - returns the list of friends of given user\r\n\r\nPossible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:\r\n\r\n```javascript\r\napp.factory('User', function ($q) {\r\n\r\n function User(name, address, friends) {\r\n this.name = name;\r\n this.address = address;\r\n this.friends = friends;\r\n }\r\n\r\n User.get = function (params) {\r\n var user = $http.get('/user/' + params.id),\r\n friends = $http.get('/friends/' + params.id);\r\n $q.all([user, friends])\r\n .then(function (user, friends) {\r\n return new User(user.name, user.address, friends);\r\n });\r\n };\r\n return User;\r\n});\r\n```\r\n\r\nThis way we create pseudo-data mapper, which adapts our API according to the SPA requirements.\r\n\r\nWe can use the `User` service by:\r\n\r\n```javascript\r\nfunction MainCtrl($scope, User) {\r\n User.get({ id: 1 })\r\n .then(function (data) {\r\n $scope.user = data;\r\n });\r\n}\r\n```\r\n\r\nAnd the following partial:\r\n\r\n```html\r\n<div>\r\n <div>\r\n Name: {{user.name}}\r\n </div>\r\n <div>\r\n Address: {{user.address}}\r\n </div>\r\n <div>\r\n Friends with ids:\r\n <ul>\r\n <li ng-repeat=\"friend in user.friends\">{{friend}}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n```\r\n\r\n#### Observer Pattern as an External Service\r\n\r\n##### About\r\n\r\nBelow is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.\r\n\r\n**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.\r\n\r\n##### Controller Example\r\n\r\nBelow example shows how to attach, notify and detach an event.\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout) {\r\n var vm = this;\r\n var id = 'vm1';\r\n\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n ObserverService.detachByEvent('let_me_know')\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n}\r\n```\r\nAlternative way to remove event\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout', '$scope'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout, $scope) {\r\n var vm = this;\r\n var id = 'vm1';\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n\r\n // Cleanup listeners when this controller is destroyed\r\n $scope.$on('$destroy', function handler() {\r\n ObserverService.detachByEvent('let_me_know')\r\n });\r\n}\r\n```\r\n\r\n## References\r\n\r\n1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.\r\n2. [AngularJS' documentation](https://docs.angularjs.org)\r\n3. [AngularJS' git repository](https://github.com/angular/angular.js)\r\n4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx)\r\n5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html)\r\n6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html)\r\n7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery)\r\n","google":"UA-18060688-20","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"AngularJS in Patterns","tagline":"\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.","body":"# AngularJS in Patterns\r\n\r\n<!--toc-->\r\n\r\n## Table of Contents\r\n\r\n* [Translations](#translations)\r\n* [Abstract](#abstract)\r\n* [Introduction](#introduction)\r\n* [AngularJS overview](#angularjs-overview)\r\n * [Partials](#partials)\r\n * [Controllers](#controllers)\r\n * [Scope](#scope)\r\n * [Directives](#directives)\r\n * [Filters](#filters)\r\n * [Services](#services)\r\n* [AngularJS Patterns](#angularjs-patterns)\r\n * [Services](#services-1)\r\n * [Singleton](#singleton)\r\n * [Factory Method](#factory-method)\r\n * [Decorator](#decorator)\r\n * [Facade](#facade)\r\n * [Proxy](#proxy)\r\n * [Active Record](#active-record)\r\n * [Intercepting Filters](#intercepting-filters)\r\n * [Directives](#directives-1)\r\n * [Composite](#composite)\r\n * [Interpreter](#interpreter)\r\n * [Template View](#template-view)\r\n * [Scope](#scope-1)\r\n * [Observer](#observer)\r\n * [Chain of Responsibilities](#chain-of-responsibilities)\r\n * [Command](#command)\r\n * [Controller](#controller-1)\r\n * [Page Controller](#page-controller)\r\n * [Others](#others)\r\n * [Module Pattern](#module-pattern)\r\n * [Data Mapper](#data-mapper)\r\n * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n* [References](#references)\r\n\r\n<!--endtoc-->\r\n\r\n## Translations\r\n\r\n- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter)\r\n- [Russian Translation](http://habrahabr.ru/post/250149/)\r\n- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko)\r\n- [Chinese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-zh-cn.md) by [carlosliu](https://github.com/carlosliu)\r\n\r\n## Abstract\r\n\r\nOne of the best ways to learn something new is to see how the things you already know are used in it.\r\nThis document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns.\r\nThe goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.\r\n\r\n## Introduction\r\n\r\nThe document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.\r\n\r\nThe last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.\r\n\r\n## AngularJS overview\r\n\r\nAngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA).\r\nSPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand.\r\nSince most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:\r\n\r\n- two-way data binding\r\n- dependency injection\r\n- separation of concerns\r\n- testability\r\n- abstraction\r\n\r\nThe separation of concerns is achieved by dividing each AngularJS application into separate components, such as:\r\n\r\n- partials\r\n- controllers\r\n- directives\r\n- services\r\n- filters\r\n\r\nThese components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.\r\n\r\n### Partials\r\n\r\nThe partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).\r\n\r\nInitially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.\r\n\r\n**Sample partial**\r\n\r\n```HTML\r\n<html ng-app>\r\n <!-- Body tag augmented with ngController directive -->\r\n <body ng-controller=\"MyController\">\r\n <input ng-model=\"foo\" value=\"bar\">\r\n <!-- Button tag with ng-click directive, and\r\n string expression 'buttonText'\r\n wrapped in \"{{ }}\" markup -->\r\n <button ng-click=\"changeFoo()\">{{buttonText}}</button>\r\n <script src=\"angular.js\"></script>\r\n </body>\r\n</html>\r\n```\r\n\r\nWith AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked.\r\n\r\n### Controllers\r\n\r\nThe AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*.\r\n\r\n```JavaScript\r\nfunction MyController($scope) {\r\n $scope.buttonText = 'Click me to change foo!';\r\n $scope.foo = 42;\r\n\r\n $scope.changeFoo = function () {\r\n $scope.foo += 1;\r\n alert('Foo changed');\r\n };\r\n}\r\n```\r\n\r\nFor example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.\r\n\r\n1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding.\r\n2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`.\r\n\r\nAll the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones.\r\n\r\n### Scope\r\n\r\nIn AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.\r\n\r\nAnother important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.\r\n\r\nScope inheritance is illustrated in the following example:\r\n\r\n```HTML\r\n<div ng-controller=\"BaseCtrl\">\r\n <div id=\"child\" ng-controller=\"ChildCtrl\">\r\n <button id=\"parent-method\" ng-click=\"foo()\">Parent method</button>\r\n <button ng-click=\"bar()\">Child method</button>\r\n </div>\r\n</div>\r\n```\r\n\r\n```JavaScript\r\nfunction BaseCtrl($scope) {\r\n $scope.foo = function () {\r\n alert('Base foo');\r\n };\r\n}\r\n\r\nfunction ChildCtrl($scope) {\r\n $scope.bar = function () {\r\n alert('Child bar');\r\n };\r\n}\r\n```\r\n\r\nWith `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`.\r\n\r\n### Directives\r\n\r\nIn AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations.\r\nEach directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:\r\n\r\n- template\r\n- compile function\r\n- link function\r\n- etc...\r\n\r\nBy citing the name of the directives they can be used inside the declarative partials.\r\n\r\nExample:\r\n\r\n```JavaScript\r\nmyModule.directive('alertButton', function () {\r\n return {\r\n template: '<button ng-transclude></button>',\r\n scope: {\r\n content: '@'\r\n },\r\n replace: true,\r\n restrict: 'E',\r\n transclude: true,\r\n link: function (scope, el) {\r\n el.click(function () {\r\n alert(scope.content);\r\n });\r\n }\r\n };\r\n});\r\n```\r\n\r\n```HTML\r\n<alert-button content=\"42\">Click me</alert-button>\r\n```\r\n\r\nIn the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted.\r\n\r\nSince the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.\r\n\r\n### Filters\r\n\r\nThe filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection.\r\n\r\nHere is a definition of a sample filter, which changes the given string to uppercase:\r\n\r\n```JavaScript\r\nmyModule.filter('uppercase', function () {\r\n return function (str) {\r\n return (str || '').toUpperCase();\r\n };\r\n});\r\n```\r\n\r\nInside a partial this filter could be used using the Unix's piping syntax:\r\n\r\n```HTML\r\n<div>{{ name | uppercase }}</div>\r\n```\r\n\r\nInside a controller the filter could be used as follows:\r\n\r\n```JavaScript\r\nfunction MyCtrl(uppercaseFilter) {\r\n $scope.name = uppercaseFilter('foo'); //FOO\r\n}\r\n```\r\n\r\n### Services\r\n\r\nEvery piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too \"fat\" the repetitive code should be placed inside a service.\r\n\r\n```JavaScript\r\nmyModule.service('Developer', function () {\r\n this.name = 'Foo';\r\n this.motherLanguage = 'JavaScript';\r\n this.live = function () {\r\n while (true) {\r\n this.code();\r\n }\r\n };\r\n});\r\n```\r\n\r\nThe service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).\r\n\r\n```JavaScript\r\nfunction MyCtrl(Developer) {\r\n var developer = new Developer();\r\n developer.live();\r\n}\r\n```\r\n\r\n## AngularJS Patterns\r\n\r\nIn the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.\r\n\r\nIn the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.\r\n\r\n### Services\r\n\r\n#### Singleton\r\n\r\n>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.\r\n\r\nIn the UML diagram bellow is illustrated the singleton design pattern.\r\n\r\n\r\n\r\nWhen given dependency is required by any component, AngularJS resolves it using the following algorithm:\r\n\r\n- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).\r\n- If the dependency exists AngularJS pass it as parameter to the component, which requires it.\r\n- If the dependency does not exists:\r\n - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.\r\n - AngularJS caches it inside the hash map mentioned above.\r\n - AngularJS passes it as parameter to the component, which requires it.\r\n\r\nWe can take better look at the AngularJS' source code, which implements the method `getService`:\r\n\r\n```JavaScript\r\nfunction getService(serviceName) {\r\n if (cache.hasOwnProperty(serviceName)) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));\r\n }\r\n return cache[serviceName];\r\n } else {\r\n try {\r\n path.unshift(serviceName);\r\n cache[serviceName] = INSTANTIATING;\r\n return cache[serviceName] = factory(serviceName);\r\n } catch (err) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n delete cache[serviceName];\r\n }\r\n throw err;\r\n } finally {\r\n path.shift();\r\n }\r\n }\r\n}\r\n```\r\n\r\nWe can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`).\r\n\r\nThis way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:\r\n\r\n- It improves the testability of your source code\r\n- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)\r\n\r\nFor further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered.\r\n\r\n#### Factory Method\r\n\r\n>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.\r\n\r\n\r\n\r\nLets consider the following snippet:\r\n\r\n```JavaScript\r\nmyModule.config(function ($provide) {\r\n $provide.provider('foo', function () {\r\n var baz = 42;\r\n return {\r\n //Factory method\r\n $get: function (bar) {\r\n var baz = bar.baz();\r\n return {\r\n baz: baz\r\n };\r\n }\r\n };\r\n });\r\n});\r\n\r\n```\r\n\r\nIn the code above we use the `config` callback in order to define new \"provider\". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.\r\n\r\nEach service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.\r\n\r\nWe can dig a little bit deeper in AngularJS' implementation:\r\n\r\n```JavaScript\r\n//...\r\n\r\ncreateInternalInjector(instanceCache, function(servicename) {\r\n var provider = providerInjector.get(servicename + providerSuffix);\r\n return instanceInjector.invoke(provider.$get, provider, undefined, servicename);\r\n}, strictDi));\r\n\r\n//...\r\n\r\nfunction invoke(fn, self, locals, serviceName){\r\n if (typeof locals === 'string') {\r\n serviceName = locals;\r\n locals = null;\r\n }\r\n\r\n var args = [],\r\n $inject = annotate(fn, strictDi, serviceName),\r\n length, i,\r\n key;\r\n\r\n for(i = 0, length = $inject.length; i < length; i++) {\r\n key = $inject[i];\r\n if (typeof key !== 'string') {\r\n throw $injectorMinErr('itkn',\r\n 'Incorrect injection token! Expected service name as string, got {0}', key);\r\n }\r\n args.push(\r\n locals && locals.hasOwnProperty(key)\r\n ? locals[key]\r\n : getService(key)\r\n );\r\n }\r\n if (!fn.$inject) {\r\n // this means that we must be an array.\r\n fn = fn[length];\r\n }\r\n\r\n return fn.apply(self, args);\r\n}\r\n```\r\n\r\nFrom the example above we can notice how the `$get` method is actually used:\r\n\r\n```JavaScript\r\ninstanceInjector.invoke(provider.$get, provider, undefined, servicename)\r\n```\r\n\r\nThe snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.\r\n\r\nIf we think in terms of the UML diagram above we can call the provider a \"ConcreteCreator\" and the actual component, which is being created a \"Product\".\r\n\r\nThere are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:\r\n\r\n- The most appropriate moment, when the component needs to be instantiated\r\n- Resolving all the dependencies required by the component\r\n- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)\r\n\r\n#### Decorator\r\n\r\n>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.\r\n\r\n\r\n\r\nAngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create \"wrapper\" of any service you have previously defined or used by a third-party:\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function (foo) {\r\n foo.bar();\r\n});\r\n\r\nmyModule.factory('foo', function () {\r\n return {\r\n bar: function () {\r\n console.log('I\\'m bar');\r\n },\r\n baz: function () {\r\n console.log('I\\'m baz');\r\n }\r\n };\r\n});\r\n\r\nmyModule.config(function ($provide) {\r\n $provide.decorator('foo', function ($delegate) {\r\n var barBackup = $delegate.bar;\r\n $delegate.bar = function () {\r\n console.log('Decorated');\r\n barBackup.apply($delegate, arguments);\r\n };\r\n return $delegate;\r\n });\r\n});\r\n```\r\nThe example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `\"foo\"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.\r\nWe decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.\r\n\r\nUsing this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop).\r\n\r\n#### Facade\r\n\r\n>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:\r\n\r\n>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;\r\n\r\n>2. make the library more readable, for the same reason;\r\n\r\n>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;\r\n\r\n>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).\r\n\r\n\r\n\r\nThere are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.\r\n\r\nFor example, lets take a look how we can create an `XMLHttpRequest` POST request:\r\n\r\n```JavaScript\r\nvar http = new XMLHttpRequest(),\r\n url = '/example/new',\r\n params = encodeURIComponent(data);\r\nhttp.open(\"POST\", url, true);\r\n\r\nhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\r\nhttp.setRequestHeader(\"Content-length\", params.length);\r\nhttp.setRequestHeader(\"Connection\", \"close\");\r\n\r\nhttp.onreadystatechange = function () {\r\n if(http.readyState == 4 && http.status == 200) {\r\n alert(http.responseText);\r\n }\r\n}\r\nhttp.send(params);\r\n```\r\nBut if we want to post this data using the AngularJS' `$http` service we can:\r\n\r\n```JavaScript\r\n$http({\r\n method: 'POST',\r\n url: '/example/new',\r\n data: data\r\n})\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nor we can even:\r\n\r\n```JavaScript\r\n$http.post('/someUrl', data)\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nThe second option provides pre-configured version, which creates a HTTP POST request to the given URL.\r\n\r\nEven higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections.\r\n\r\n#### Proxy\r\n\r\n>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.\r\n\r\n\r\n\r\nWe can distinguish three different types of proxy:\r\n\r\n- Virtual Proxy\r\n- Remote Proxy\r\n- Protection Proxy\r\n\r\nIn this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.\r\n\r\nIn the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = User.get({ id: 42 });\r\nconsole.log(user); //{}\r\n```\r\n\r\n`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.\r\n\r\nHow does this works with AngularJS? Well, lets consider the following snippet:\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $resource) {\r\n var User = $resource('/users/:id'),\r\n $scope.user = User.get({ id: 42 });\r\n}\r\n```\r\n\r\n```html\r\n<span ng-bind=\"user.name\"></span>\r\n```\r\nInitially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view.\r\n\r\n#### Active Record\r\n\r\n>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.\r\n\r\n\r\n\r\nAngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.\r\n\r\nAccording to the AngularJS' documentation `$resource` is:\r\n\r\n>A factory which creates a resource object that lets you interact with RESTful server-side data sources.\r\n>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.\r\n\r\nHere is how `$resource` could be used:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = new User({\r\n name: 'foo',\r\n age : 42\r\n });\r\n\r\nuser.$save();\r\n```\r\n\r\nThe call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.\r\n\r\nThis way we can use the constructor function and its static methods by:\r\n\r\n```JavaScript\r\nUser.get({ userid: userid });\r\n```\r\n\r\nThe code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)).\r\n\r\nYou can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource).\r\n\r\nSince Martin Fowler states that\r\n\r\n> responsibility of the Active Record object is to take care of the communication with the databse in order to create...\r\n\r\n`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as \"Active Record like RESTful communication\".\r\n\r\n#### Intercepting Filters\r\n\r\n>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.\r\n\r\n\r\n\r\nIn some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.\r\n\r\nIn AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`.\r\n\r\n`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error.\r\n\r\nHere is a basic example how you can add interceptors using object literal:\r\n\r\n```JavaScript\r\n$httpProvider.interceptors.push(function($q, dependency1, dependency2) {\r\n return {\r\n 'request': function(config) {\r\n // same as above\r\n },\r\n 'response': function(response) {\r\n // same as above\r\n }\r\n };\r\n});\r\n```\r\n\r\n### Directives\r\n\r\n#### Composite\r\n\r\n>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to \"compose\" objects into tree structures to represent part-whole hierarchies.\r\n\r\n\r\n\r\nAccording to the Gang of Four, MVC is nothing more than combination of:\r\n\r\n- Strategy\r\n- Composite\r\n- Observer\r\n\r\nThey state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.\r\n\r\nLets look at the following example:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body>\r\n <zippy title=\"Zippy\">\r\n Zippy!\r\n </zippy>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nmyModule.directive('zippy', function () {\r\n return {\r\n restrict: 'E',\r\n template: '<div><div class=\"header\"></div><div class=\"content\" ng-transclude></div></div>',\r\n link: function (scope, el) {\r\n el.find('.header').click(function () {\r\n el.find('.content').toggle();\r\n });\r\n }\r\n }\r\n});\r\n```\r\n\r\nThis example defines a simple directive, which is a UI component. The defined component (called \"zippy\") has header and content. Click on its header toggles the visibility of the content.\r\n\r\nFrom the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on...\r\n\r\nIn the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.\r\n\r\n#### Interpreter\r\n\r\n>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.\r\n\r\n\r\n\r\nBehind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript.\r\nThe main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:\r\n\r\n- may contain filters with UNIX like pipe syntax\r\n- don't throw any errors\r\n- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)\r\n- are evaluated in given context (the context of the current `$scope`)\r\n\r\nInside the `$parse` service are defined two main components:\r\n\r\n```JavaScript\r\n//Responsible for converting given string into tokens\r\nvar Lexer;\r\n//Responsible for parsing the tokens and evaluating the expression\r\nvar Parser;\r\n```\r\n\r\nOnce given expression have been tokenized it is cached internally, because of performance concerns.\r\n\r\nThe terminal expressions in the AngularJS DSL are defined as follows:\r\n\r\n```JavaScript\r\nvar OPERATORS = {\r\n /* jshint bitwise : false */\r\n 'null':function(){return null;},\r\n 'true':function(){return true;},\r\n 'false':function(){return false;},\r\n undefined:noop,\r\n '+':function(self, locals, a,b){\r\n //...\r\n },\r\n '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},\r\n '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},\r\n '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},\r\n '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},\r\n '=':noop,\r\n '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},\r\n '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},\r\n '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},\r\n '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},\r\n '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},\r\n '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},\r\n '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},\r\n '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},\r\n '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},\r\n '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},\r\n '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},\r\n '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},\r\n '!':function(self, locals, a){return !a(self, locals);}\r\n};\r\n```\r\n\r\nWe can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface.\r\n\r\nEach `Client` interprets given AngularJS expression in a specific context - specific scope.\r\n\r\nFew sample AngularJS expressions are:\r\n\r\n```JavaScript\r\n// toUpperCase filter is applied to the result of the expression\r\n// (foo) ? bar : baz\r\n(foo) ? bar : baz | toUpperCase\r\n```\r\n\r\n#### Template View\r\n\r\n> Renders information into HTML by embedding markers in an HTML page.\r\n\r\n\r\n\r\nThe dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.\r\n\r\nTemplates are very commonly used especially in the back-end.\r\nFor example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.\r\n\r\nFor JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript.\r\n\r\nFor example:\r\n\r\n```html\r\n<script type=\"template/mustache\">\r\n <h2>Names</h2>\r\n {{#names}}\r\n <strong>{{name}}</strong>\r\n {{/names}}\r\n</script>\r\n```\r\n\r\nThe template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.\r\n\r\nFor example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get:\r\n\r\n```html\r\n<h2>Names</h2>\r\n <strong>foo</strong>\r\n <strong>bar</strong>\r\n <strong>baz</strong>\r\n```\r\n\r\nAngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are.\r\nWhat AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.\r\n\r\nFor example:\r\n\r\n```html\r\n<ul ng-repeat=\"name in names\">\r\n <li>{{name}}</li>\r\n</ul>\r\n```\r\n\r\nin the context of the scope:\r\n\r\n```javascript\r\n$scope.names = ['foo', 'bar', 'baz'];\r\n```\r\n\r\nwill produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead.\r\n\r\n\r\n### Scope\r\n\r\n#### Observer\r\n\r\n>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.\r\n\r\n\r\n\r\nThere are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.\r\n\r\nEach AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$on('event-name', function handler() {\r\n //body\r\n });\r\n}\r\n```\r\n\r\nIn this way the current scope \"subscribes\" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.\r\n\r\nThe methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.\r\nFor example:\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$emit('event-name', { foo: 'bar' });\r\n}\r\n```\r\n\r\nThe scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.\r\n\r\nAnalogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.\r\nEach scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).\r\n\r\nIn the JavaScript community this pattern is better known as publish/subscribe.\r\n\r\nFor a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n\r\n#### Chain of Responsibilities\r\n\r\n>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.\r\n\r\n\r\n\r\nAs stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are \"isolated\", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.\r\n\r\nWhen `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:\r\n\r\n- Handle the event and pass it to the next scope in the chain\r\n- Handle the event and stop its propagation\r\n- Pass the event to the next scope in the chain without handling it\r\n- Stop the event propagation without handling it\r\n\r\nIn the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `\"foo received\"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback.\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function ($scope) {\r\n $scope.$on('foo', function () {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ParentCtrl', function ($scope) {\r\n $scope.$on('foo', function (e) {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ChildCtrl', function ($scope) {\r\n $scope.$emit('foo');\r\n});\r\n```\r\n\r\nThe different handlers from the UML diagram above are the different scopes, injected to the controllers.\r\n\r\n#### Command\r\n\r\n>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.\r\n\r\n\r\n\r\nBefore continuing with the application of the command pattern lets describe how AngularJS implements data binding.\r\n\r\nWhen we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can:\r\n\r\n```html\r\n<span ng-bind=\"foo\"></span>\r\n```\r\n\r\nNow each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:\r\n\r\n```html\r\n<span ng-bind=\"foo + ' ' + bar | uppercase\"></span>\r\n```\r\n\r\nIn the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene?\r\n\r\nEach `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch(\"foo + ' ' + bar | uppercase\", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.\r\n\r\nHere are the first a couple of lines of the implementation of `$watch`:\r\n\r\n```javascript\r\n$watch: function(watchExp, listener, objectEquality) {\r\n var scope = this,\r\n get = compileToFn(watchExp, 'watch'),\r\n array = scope.$$watchers,\r\n watcher = {\r\n fn: listener,\r\n last: initWatchVal,\r\n get: get,\r\n exp: watchExp,\r\n eq: !!objectEquality\r\n };\r\n//...\r\n```\r\n\r\nWe can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`\"$digest\"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`.\r\n\r\n### Controllers\r\n\r\n#### Page Controller\r\n\r\n>An object that handles a request for a specific page or action on a Web site. Martin Fowler\r\n\r\n\r\n\r\nAccording to [4](#references) the page controller:\r\n\r\n>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code\r\n\r\nSince there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.\r\n\r\nSimilarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.\r\n\r\nThe controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.\r\nHere is an example hierarchy between few controllers:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body ng-controller=\"MainCtrl\">\r\n <div ng-controller=\"ChildCtrl\">\r\n <span>{{user.name}}</span>\r\n <button ng-click=\"click()\">Click</button>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $location, User) {\r\n if (!User.isAuthenticated()) {\r\n $location.path('/unauthenticated');\r\n }\r\n}\r\n\r\nfunction ChildCtrl($scope, User) {\r\n $scope.click = function () {\r\n alert('You clicked me!');\r\n };\r\n $scope.user = User.get(0);\r\n}\r\n```\r\n\r\nThis example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.\r\n\r\nThe `ChildCtrl` is responsible for handling actions such as clicking the button with label `\"Click\"` and exposing the model to the view, by attaching it to the scope.\r\n\r\n### Others\r\n\r\n#### Module Pattern\r\n\r\nThis is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.\r\n\r\nUsing the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:\r\n\r\n```javascript\r\nvar Page = (function () {\r\n\r\n var title;\r\n\r\n function setTitle(t) {\r\n document.title = t;\r\n title = t;\r\n }\r\n\r\n function getTitle() {\r\n return title;\r\n }\r\n\r\n return {\r\n setTitle: setTitle,\r\n getTitle: getTitle\r\n };\r\n}());\r\n```\r\n\r\nIn the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.\r\n\r\nIn this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE.\r\n\r\nThe module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:\r\n\r\n```javascript\r\napp.factory('foo', function () {\r\n\r\n function privateMember() {\r\n //body...\r\n }\r\n\r\n function publicMember() {\r\n //body...\r\n privateMember();\r\n //body\r\n }\r\n\r\n return {\r\n publicMember: publicMember\r\n };\r\n});\r\n```\r\n\r\nOnce we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.\r\n\r\n#### Data Mapper\r\n\r\n>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.\r\n\r\n\r\n\r\nAs the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).\r\n\r\nUsually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.\r\n\r\nFor instance, lets assume we have application in which each user has:\r\n\r\n- name\r\n- address\r\n- list of friends\r\n\r\nAnd our API has the methods:\r\n\r\n- `GET /user/:id` - returns the user's name and the address of given user\r\n- `GET /friends/:id` - returns the list of friends of given user\r\n\r\nPossible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:\r\n\r\n```javascript\r\napp.factory('User', function ($q) {\r\n\r\n function User(name, address, friends) {\r\n this.name = name;\r\n this.address = address;\r\n this.friends = friends;\r\n }\r\n\r\n User.get = function (params) {\r\n var user = $http.get('/user/' + params.id),\r\n friends = $http.get('/friends/' + params.id);\r\n $q.all([user, friends])\r\n .then(function (user, friends) {\r\n return new User(user.name, user.address, friends);\r\n });\r\n };\r\n return User;\r\n});\r\n```\r\n\r\nThis way we create pseudo-data mapper, which adapts our API according to the SPA requirements.\r\n\r\nWe can use the `User` service by:\r\n\r\n```javascript\r\nfunction MainCtrl($scope, User) {\r\n User.get({ id: 1 })\r\n .then(function (data) {\r\n $scope.user = data;\r\n });\r\n}\r\n```\r\n\r\nAnd the following partial:\r\n\r\n```html\r\n<div>\r\n <div>\r\n Name: {{user.name}}\r\n </div>\r\n <div>\r\n Address: {{user.address}}\r\n </div>\r\n <div>\r\n Friends with ids:\r\n <ul>\r\n <li ng-repeat=\"friend in user.friends\">{{friend}}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n```\r\n\r\n#### Observer Pattern as an External Service\r\n\r\n##### About\r\n\r\nBelow is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.\r\n\r\n**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.\r\n\r\n##### Controller Example\r\n\r\nBelow example shows how to attach, notify and detach an event.\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout) {\r\n var vm = this;\r\n var id = 'vm1';\r\n\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n ObserverService.detachByEvent('let_me_know')\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n}\r\n```\r\nAlternative way to remove event\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout', '$scope'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout, $scope) {\r\n var vm = this;\r\n var id = 'vm1';\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n\r\n // Cleanup listeners when this controller is destroyed\r\n $scope.$on('$destroy', function handler() {\r\n ObserverService.detachByEvent('let_me_know')\r\n });\r\n}\r\n```\r\n\r\n## References\r\n\r\n1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.\r\n2. [AngularJS' documentation](https://docs.angularjs.org)\r\n3. [AngularJS' git repository](https://github.com/angular/angular.js)\r\n4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx)\r\n5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html)\r\n6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html)\r\n7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery)\r\n","google":"UA-18060688-20","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From e9280b8a9a6cfede5a20f653000ff624fdfe41ed Mon Sep 17 00:00:00 2001 From: Minko Gechev <mgechev@gmail.com> Date: Sun, 8 Jan 2017 22:01:20 +0200 Subject: [PATCH 17/19] Set theme jekyll-theme-cayman and migrate Page Generator content --- _config.yml | 8 + index.html | 1267 --------------------------------------------------- index.md | 1164 ++++++++++++++++++++++++++++++++++++++++++++++ params.json | 1 - 4 files changed, 1172 insertions(+), 1268 deletions(-) create mode 100644 _config.yml delete mode 100644 index.html create mode 100644 index.md delete mode 100644 params.json diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..b10b14b --- /dev/null +++ b/_config.yml @@ -0,0 +1,8 @@ +title: AngularJS in Patterns +description: "\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application." +google_analytics: UA-18060688-20 +show_downloads: true +theme: jekyll-theme-cayman + +gems: + - jekyll-mentions diff --git a/index.html b/index.html deleted file mode 100644 index de9411d..0000000 --- a/index.html +++ /dev/null @@ -1,1267 +0,0 @@ -<!DOCTYPE html> -<html lang="en-us"> - <head> - <meta charset="UTF-8"> - <title>AngularJS in Patterns by mgechev</title> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen"> - <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'> - <link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen"> - <link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen"> - </head> - <body> - <section class="page-header"> - <h1 class="project-name">AngularJS in Patterns</h1> - <h2 class="project-tagline">"AngularJS in Patterns" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.</h2> - <a href="https://github.com/mgechev/angularjs-in-patterns" class="btn">View on GitHub</a> - <a href="https://github.com/mgechev/angularjs-in-patterns/zipball/master" class="btn">Download .zip</a> - <a href="https://github.com/mgechev/angularjs-in-patterns/tarball/master" class="btn">Download .tar.gz</a> - </section> - - <section class="main-content"> - <h1> -<a id="angularjs-in-patterns" class="anchor" href="#angularjs-in-patterns" aria-hidden="true"><span class="octicon octicon-link"></span></a>AngularJS in Patterns</h1> - - - -<h2> -<a id="table-of-contents" class="anchor" href="#table-of-contents" aria-hidden="true"><span class="octicon octicon-link"></span></a>Table of Contents</h2> - -<ul> -<li><a href="#translations">Translations</a></li> -<li><a href="#abstract">Abstract</a></li> -<li><a href="#introduction">Introduction</a></li> -<li> -<a href="#angularjs-overview">AngularJS overview</a> - -<ul> -<li><a href="#partials">Partials</a></li> -<li><a href="#controllers">Controllers</a></li> -<li><a href="#scope">Scope</a></li> -<li><a href="#directives">Directives</a></li> -<li><a href="#filters">Filters</a></li> -<li><a href="#services">Services</a></li> -</ul> -</li> -<li> -<a href="#angularjs-patterns">AngularJS Patterns</a> - -<ul> -<li> -<a href="#services-1">Services</a> - -<ul> -<li><a href="#singleton">Singleton</a></li> -<li><a href="#factory-method">Factory Method</a></li> -<li><a href="#decorator">Decorator</a></li> -<li><a href="#facade">Facade</a></li> -<li><a href="#proxy">Proxy</a></li> -<li><a href="#active-record">Active Record</a></li> -<li><a href="#intercepting-filters">Intercepting Filters</a></li> -</ul> -</li> -<li> -<a href="#directives-1">Directives</a> - -<ul> -<li><a href="#composite">Composite</a></li> -<li><a href="#interpreter">Interpreter</a></li> -<li><a href="#template-view">Template View</a></li> -</ul> -</li> -<li> -<a href="#scope-1">Scope</a> - -<ul> -<li><a href="#observer">Observer</a></li> -<li><a href="#chain-of-responsibilities">Chain of Responsibilities</a></li> -<li><a href="#command">Command</a></li> -</ul> -</li> -<li> -<a href="#controller-1">Controller</a> - -<ul> -<li><a href="#page-controller">Page Controller</a></li> -</ul> -</li> -<li> -<a href="#others">Others</a> - -<ul> -<li><a href="#module-pattern">Module Pattern</a></li> -<li><a href="#data-mapper">Data Mapper</a></li> -<li><a href="#observer-pattern-as-an-external-service">Observer Pattern as an External Service</a></li> -</ul> -</li> -</ul> -</li> -<li><a href="#references">References</a></li> -</ul> - - - -<h2> -<a id="translations" class="anchor" href="#translations" aria-hidden="true"><span class="octicon octicon-link"></span></a>Translations</h2> - -<ul> -<li> -<a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md">Japanese Translation</a> by <a href="https://twitter.com/morizotter">morizotter</a> -</li> -<li><a href="http://habrahabr.ru/post/250149/">Russian Translation</a></li> -<li> -<a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md">French Translation</a> by <a href="https://github.com/manekinekko">manekinekko</a> -</li> -<li> -<a href="https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-zh-cn.md">Chinese Translation</a> by <a href="https://github.com/carlosliu">carlosliu</a> -</li> -</ul> - -<h2> -<a id="abstract" class="anchor" href="#abstract" aria-hidden="true"><span class="octicon octicon-link"></span></a>Abstract</h2> - -<p>One of the best ways to learn something new is to see how the things you already know are used in it. -This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. -The goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.</p> - -<h2> -<a id="introduction" class="anchor" href="#introduction" aria-hidden="true"><span class="octicon octicon-link"></span></a>Introduction</h2> - -<p>The document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.</p> - -<p>The last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.</p> - -<h2> -<a id="angularjs-overview" class="anchor" href="#angularjs-overview" aria-hidden="true"><span class="octicon octicon-link"></span></a>AngularJS overview</h2> - -<p>AngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA). -SPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand. -Since most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:</p> - -<ul> -<li>two-way data binding</li> -<li>dependency injection</li> -<li>separation of concerns</li> -<li>testability</li> -<li>abstraction</li> -</ul> - -<p>The separation of concerns is achieved by dividing each AngularJS application into separate components, such as:</p> - -<ul> -<li>partials</li> -<li>controllers</li> -<li>directives</li> -<li>services</li> -<li>filters</li> -</ul> - -<p>These components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.</p> - -<h3> -<a id="partials" class="anchor" href="#partials" aria-hidden="true"><span class="octicon octicon-link"></span></a>Partials</h3> - -<p>The partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).</p> - -<p>Initially each SPA loads <code>index.html</code> file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.</p> - -<p><strong>Sample partial</strong></p> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">html</span> <span class="pl-e">ng-app</span>> - <span class="pl-c"><!-- Body tag augmented with ngController directive --></span> - <<span class="pl-ent">body</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>MyController<span class="pl-pds">"</span></span>> - <<span class="pl-ent">input</span> <span class="pl-e">ng-model</span>=<span class="pl-s"><span class="pl-pds">"</span>foo<span class="pl-pds">"</span></span> <span class="pl-e">value</span>=<span class="pl-s"><span class="pl-pds">"</span>bar<span class="pl-pds">"</span></span>> - <span class="pl-c"><!-- Button tag with ng-click directive, and</span> -<span class="pl-c"> string expression 'buttonText'</span> -<span class="pl-c"> wrapped in "{{ }}" markup --></span> - <<span class="pl-ent">button</span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>changeFoo()<span class="pl-pds">"</span></span>>{{buttonText}}</<span class="pl-ent">button</span>> -<span class="pl-s1"> <<span class="pl-ent">script</span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>angular.js<span class="pl-pds">"</span></span>></<span class="pl-ent">script</span>></span> - </<span class="pl-ent">body</span>> -</<span class="pl-ent">html</span>></pre></div> - -<p>With AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute <code>ng-click</code> states that the method <code>changeFoo</code> of the current <em>scope</em> will be invoked.</p> - -<h3> -<a id="controllers" class="anchor" href="#controllers" aria-hidden="true"><span class="octicon octicon-link"></span></a>Controllers</h3> - -<p>The AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the <em>scope</em>. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the <em>model</em> to the partials by attaching data to the <em>scope</em>. We can think of this data as <em>view model</em>.</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MyController</span>(<span class="pl-smi">$scope</span>) { - $scope.buttonText <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Click me to change foo!<span class="pl-pds">'</span></span>; - $scope.foo <span class="pl-k">=</span> <span class="pl-c1">42</span>; - - <span class="pl-c1">$scope</span>.<span class="pl-en">changeFoo</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - $scope.foo <span class="pl-k">+=</span> <span class="pl-c1">1</span>; - <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>Foo changed<span class="pl-pds">'</span></span>); - }; -}</pre></div> - -<p>For example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.</p> - -<ol> -<li>Change the value of <code>foo</code> by typing in the input box. This will immediately reflect the value of <code>foo</code> because of the two-way data binding.</li> -<li>Change the value of <code>foo</code> by clicking the button, which will be labeled <code>Click me to change foo!</code>.</li> -</ol> - -<p>All the custom elements, attributes, comments or classes could be recognized as AngularJS <em>directives</em> if they are previously defined as ones.</p> - -<h3> -<a id="scope" class="anchor" href="#scope" aria-hidden="true"><span class="octicon octicon-link"></span></a>Scope</h3> - -<p>In AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate <em>directives</em>, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.</p> - -<p>Another important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as <em>isolated</em>). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.</p> - -<p>Scope inheritance is illustrated in the following example:</p> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">div</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>BaseCtrl<span class="pl-pds">"</span></span>> - <<span class="pl-ent">div</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>child<span class="pl-pds">"</span></span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>ChildCtrl<span class="pl-pds">"</span></span>> - <<span class="pl-ent">button</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>parent-method<span class="pl-pds">"</span></span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>foo()<span class="pl-pds">"</span></span>>Parent method</<span class="pl-ent">button</span>> - <<span class="pl-ent">button</span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>bar()<span class="pl-pds">"</span></span>>Child method</<span class="pl-ent">button</span>> - </<span class="pl-ent">div</span>> -</<span class="pl-ent">div</span>></pre></div> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">BaseCtrl</span>(<span class="pl-smi">$scope</span>) { - <span class="pl-c1">$scope</span>.<span class="pl-en">foo</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>Base foo<span class="pl-pds">'</span></span>); - }; -} - -<span class="pl-k">function</span> <span class="pl-en">ChildCtrl</span>(<span class="pl-smi">$scope</span>) { - <span class="pl-c1">$scope</span>.<span class="pl-en">bar</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>Child bar<span class="pl-pds">'</span></span>); - }; -}</pre></div> - -<p>With <code>div#child</code> is associated <code>ChildCtrl</code> but since the scope injected inside <code>ChildCtrl</code> inherits prototypically from its parent scope (i.e. the one injected inside <code>BaseCtrl</code>) the method <code>foo</code> is accessible by <code>button#parent-method</code>.</p> - -<h3> -<a id="directives" class="anchor" href="#directives" aria-hidden="true"><span class="octicon octicon-link"></span></a>Directives</h3> - -<p>In AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations. -Each directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of <em>postLink</em> function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:</p> - -<ul> -<li>template</li> -<li>compile function</li> -<li>link function</li> -<li>etc...</li> -</ul> - -<p>By citing the name of the directives they can be used inside the declarative partials.</p> - -<p>Example:</p> - -<div class="highlight highlight-source-js"><pre>myModule.directive(<span class="pl-s"><span class="pl-pds">'</span>alertButton<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - <span class="pl-k">return</span> { - template<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span><button ng-transclude></button><span class="pl-pds">'</span></span>, - scope<span class="pl-k">:</span> { - content<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>@<span class="pl-pds">'</span></span> - }, - replace<span class="pl-k">:</span> <span class="pl-c1">true</span>, - restrict<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>E<span class="pl-pds">'</span></span>, - transclude<span class="pl-k">:</span> <span class="pl-c1">true</span>, - <span class="pl-en">link</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span class="pl-smi">scope</span>, <span class="pl-smi">el</span>) { - el.<span class="pl-c1">click</span>(<span class="pl-k">function</span> () { - <span class="pl-c1">alert</span>(scope.<span class="pl-c1">content</span>); - }); - } - }; -});</pre></div> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">alert</span><span class="pl-e">-button</span> <span class="pl-e">content</span>=<span class="pl-s"><span class="pl-pds">"</span>42<span class="pl-pds">"</span></span>>Click me</<span class="pl-ent">alert</span><span class="pl-e">-button</span>></pre></div> - -<p>In the example above the tag <code><alert-button></alert-button></code> will be replaced button element. When the user clicks on the button the string <code>42</code> will be alerted.</p> - -<p>Since the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.</p> - -<h3> -<a id="filters" class="anchor" href="#filters" aria-hidden="true"><span class="octicon octicon-link"></span></a>Filters</h3> - -<p>The filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, <em>services</em> and other filters through Dependency Injection.</p> - -<p>Here is a definition of a sample filter, which changes the given string to uppercase:</p> - -<div class="highlight highlight-source-js"><pre>myModule.filter(<span class="pl-s"><span class="pl-pds">'</span>uppercase<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - <span class="pl-k">return</span> <span class="pl-k">function</span> (<span class="pl-smi">str</span>) { - <span class="pl-k">return</span> (str <span class="pl-k">||</span> <span class="pl-s"><span class="pl-pds">'</span><span class="pl-pds">'</span></span>).<span class="pl-c1">toUpperCase</span>(); - }; -});</pre></div> - -<p>Inside a partial this filter could be used using the Unix's piping syntax:</p> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">div</span>>{{ name | uppercase }}</<span class="pl-ent">div</span>></pre></div> - -<p>Inside a controller the filter could be used as follows:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MyCtrl</span>(<span class="pl-smi">uppercaseFilter</span>) { - $scope.<span class="pl-c1">name</span> <span class="pl-k">=</span> uppercaseFilter(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>); <span class="pl-c">//FOO</span> -}</pre></div> - -<h3> -<a id="services" class="anchor" href="#services" aria-hidden="true"><span class="octicon octicon-link"></span></a>Services</h3> - -<p>Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service.</p> - -<div class="highlight highlight-source-js"><pre>myModule.service(<span class="pl-s"><span class="pl-pds">'</span>Developer<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - <span class="pl-v">this</span>.<span class="pl-c1">name</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Foo<span class="pl-pds">'</span></span>; - <span class="pl-v">this</span>.motherLanguage <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>JavaScript<span class="pl-pds">'</span></span>; - <span class="pl-c1">this</span>.<span class="pl-en">live</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - <span class="pl-k">while</span> (<span class="pl-c1">true</span>) { - <span class="pl-v">this</span>.<span class="pl-c1">code</span>(); - } - }; -});</pre></div> - -<p>The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MyCtrl</span>(<span class="pl-smi">Developer</span>) { - <span class="pl-k">var</span> developer <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Developer</span>(); - developer.live(); -}</pre></div> - -<h2> -<a id="angularjs-patterns" class="anchor" href="#angularjs-patterns" aria-hidden="true"><span class="octicon octicon-link"></span></a>AngularJS Patterns</h2> - -<p>In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.</p> - -<p>In the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.</p> - -<h3> -<a id="services-1" class="anchor" href="#services-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Services</h3> - -<h4> -<a id="singleton" class="anchor" href="#singleton" aria-hidden="true"><span class="octicon octicon-link"></span></a>Singleton</h4> - -<blockquote> -<p>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.</p> -</blockquote> - -<p>In the UML diagram bellow is illustrated the singleton design pattern.</p> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/singleton.svg" alt="Singleton" title="Fig. 1"></p> - -<p>When given dependency is required by any component, AngularJS resolves it using the following algorithm:</p> - -<ul> -<li>Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).</li> -<li>If the dependency exists AngularJS pass it as parameter to the component, which requires it.</li> -<li>If the dependency does not exists: - -<ul> -<li>AngularJS instantiate it by calling the factory method of its provider (i.e. <code>$get</code>). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.</li> -<li>AngularJS caches it inside the hash map mentioned above.</li> -<li>AngularJS passes it as parameter to the component, which requires it.</li> -</ul> -</li> -</ul> - -<p>We can take better look at the AngularJS' source code, which implements the method <code>getService</code>:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">getService</span>(<span class="pl-smi">serviceName</span>) { - <span class="pl-k">if</span> (cache.hasOwnProperty(serviceName)) { - <span class="pl-k">if</span> (cache[serviceName] <span class="pl-k">===</span> <span class="pl-c1">INSTANTIATING</span>) { - <span class="pl-k">throw</span> $injectorMinErr(<span class="pl-s"><span class="pl-pds">'</span>cdep<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>Circular dependency found: {0}<span class="pl-pds">'</span></span>, path.<span class="pl-c1">join</span>(<span class="pl-s"><span class="pl-pds">'</span> <- <span class="pl-pds">'</span></span>)); - } - <span class="pl-k">return</span> cache[serviceName]; - } <span class="pl-k">else</span> { - <span class="pl-k">try</span> { - path.<span class="pl-c1">unshift</span>(serviceName); - cache[serviceName] <span class="pl-k">=</span> <span class="pl-c1">INSTANTIATING</span>; - <span class="pl-k">return</span> cache[serviceName] <span class="pl-k">=</span> factory(serviceName); - } <span class="pl-k">catch</span> (err) { - <span class="pl-k">if</span> (cache[serviceName] <span class="pl-k">===</span> <span class="pl-c1">INSTANTIATING</span>) { - <span class="pl-k">delete</span> cache[serviceName]; - } - <span class="pl-k">throw</span> err; - } <span class="pl-k">finally</span> { - path.<span class="pl-c1">shift</span>(); - } - } -}</pre></div> - -<p>We can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as <code>cache</code>).</p> - -<p>This way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:</p> - -<ul> -<li>It improves the testability of your source code</li> -<li>You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)</li> -</ul> - -<p>For further discussion on this topic Misko Hevery's <a href="http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html">article</a> in the Google Testing blog could be considered.</p> - -<h4> -<a id="factory-method" class="anchor" href="#factory-method" aria-hidden="true"><span class="octicon octicon-link"></span></a>Factory Method</h4> - -<blockquote> -<p>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/factory-method.svg" alt="Factory Method" title="Fig. 2"></p> - -<p>Lets consider the following snippet:</p> - -<div class="highlight highlight-source-js"><pre>myModule.config(<span class="pl-k">function</span> (<span class="pl-smi">$provide</span>) { - $provide.provider(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - <span class="pl-k">var</span> baz <span class="pl-k">=</span> <span class="pl-c1">42</span>; - <span class="pl-k">return</span> { - <span class="pl-c">//Factory method</span> - $<span class="pl-en">get</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span class="pl-smi">bar</span>) { - <span class="pl-k">var</span> baz <span class="pl-k">=</span> bar.baz(); - <span class="pl-k">return</span> { - baz<span class="pl-k">:</span> baz - }; - } - }; - }); -}); -</pre></div> - -<p>In the code above we use the <code>config</code> callback in order to define new "provider". Provider is an object, which has a method called <code>$get</code>. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.</p> - -<p>Each service, filter, directive and controller has a provider (i.e. object which factory method, called <code>$get</code>), which is responsible for creating the component's instance.</p> - -<p>We can dig a little bit deeper in AngularJS' implementation:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-c">//...</span> - -createInternalInjector(instanceCache, <span class="pl-k">function</span>(<span class="pl-smi">servicename</span>) { - <span class="pl-k">var</span> provider <span class="pl-k">=</span> providerInjector.get(servicename <span class="pl-k">+</span> providerSuffix); - <span class="pl-k">return</span> instanceInjector.invoke(provider.$get, provider, <span class="pl-c1">undefined</span>, servicename); -}, strictDi)); - -<span class="pl-c">//...</span> - -<span class="pl-k">function</span> <span class="pl-en">invoke</span>(<span class="pl-smi">fn</span>, <span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">serviceName</span>){ - <span class="pl-k">if</span> (<span class="pl-k">typeof</span> locals <span class="pl-k">===</span> <span class="pl-s"><span class="pl-pds">'</span>string<span class="pl-pds">'</span></span>) { - serviceName <span class="pl-k">=</span> locals; - locals <span class="pl-k">=</span> <span class="pl-c1">null</span>; - } - - <span class="pl-k">var</span> args <span class="pl-k">=</span> [], - $inject <span class="pl-k">=</span> annotate(fn, strictDi, serviceName), - length, i, - key; - - <span class="pl-k">for</span>(i <span class="pl-k">=</span> <span class="pl-c1">0</span>, length <span class="pl-k">=</span> $inject.<span class="pl-c1">length</span>; i <span class="pl-k"><</span> length; i<span class="pl-k">++</span>) { - key <span class="pl-k">=</span> $inject[i]; - <span class="pl-k">if</span> (<span class="pl-k">typeof</span> key <span class="pl-k">!==</span> <span class="pl-s"><span class="pl-pds">'</span>string<span class="pl-pds">'</span></span>) { - <span class="pl-k">throw</span> $injectorMinErr(<span class="pl-s"><span class="pl-pds">'</span>itkn<span class="pl-pds">'</span></span>, - <span class="pl-s"><span class="pl-pds">'</span>Incorrect injection token! Expected service name as string, got {0}<span class="pl-pds">'</span></span>, key); - } - args.<span class="pl-c1">push</span>( - locals <span class="pl-k">&&</span> locals.hasOwnProperty(key) - <span class="pl-k">?</span> locals[key] - <span class="pl-k">:</span> getService(key) - ); - } - <span class="pl-k">if</span> (<span class="pl-k">!</span>fn.$inject) { - <span class="pl-c">// this means that we must be an array.</span> - fn <span class="pl-k">=</span> fn[length]; - } - - <span class="pl-k">return</span> fn.<span class="pl-c1">apply</span>(self, args); -}</pre></div> - -<p>From the example above we can notice how the <code>$get</code> method is actually used:</p> - -<div class="highlight highlight-source-js"><pre>instanceInjector.invoke(provider.$get, provider, <span class="pl-c1">undefined</span>, servicename)</pre></div> - -<p>The snippet above calls the <code>invoke</code> method of <code>instanceInjector</code> with the factory method (i.e. <code>$get</code>) of given service, as first argument. Inside <code>invoke</code>'s body <code>annotate</code> is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: <code>fn.apply(self, args)</code>.</p> - -<p>If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product".</p> - -<p>There are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:</p> - -<ul> -<li>The most appropriate moment, when the component needs to be instantiated</li> -<li>Resolving all the dependencies required by the component</li> -<li>The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)</li> -</ul> - -<h4> -<a id="decorator" class="anchor" href="#decorator" aria-hidden="true"><span class="octicon octicon-link"></span></a>Decorator</h4> - -<blockquote> -<p>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/decorator.svg" alt="Decorator" title="Fig. 4"></p> - -<p>AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method <code>decorator</code> of <code>$provide</code> you can create "wrapper" of any service you have previously defined or used by a third-party:</p> - -<div class="highlight highlight-source-js"><pre>myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">foo</span>) { - foo.bar(); -}); - -myModule.factory(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - <span class="pl-k">return</span> { - <span class="pl-en">bar</span><span class="pl-k">:</span> <span class="pl-k">function</span> () { - <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m bar<span class="pl-pds">'</span></span>); - }, - <span class="pl-en">baz</span><span class="pl-k">:</span> <span class="pl-k">function</span> () { - <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>I<span class="pl-cce">\'</span>m baz<span class="pl-pds">'</span></span>); - } - }; -}); - -myModule.config(<span class="pl-k">function</span> (<span class="pl-smi">$provide</span>) { - $provide.decorator(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$delegate</span>) { - <span class="pl-k">var</span> barBackup <span class="pl-k">=</span> $delegate.bar; - <span class="pl-c1">$delegate</span>.<span class="pl-en">bar</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>Decorated<span class="pl-pds">'</span></span>); - barBackup.<span class="pl-c1">apply</span>($delegate, arguments); - }; - <span class="pl-k">return</span> $delegate; - }); -});</pre></div> - -<p>The example above defines new service called <code>foo</code>. In the <code>config</code> callback is called the method <code>$provide.decorator</code> with first argument <code>"foo"</code>, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. <code>$delegate</code> keeps reference to the original service <code>foo</code>. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function. -We decorate the service by overriding its method <code>bar</code>. The actual decoration is simply extending <code>bar</code> by invoking one more <code>console.log statement</code> - <code>console.log('Decorated');</code> and after that call the original <code>bar</code> method with the appropriate context.</p> - -<p>Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">aspect-oriented programming</a>. The only AOP framework for AngularJS I'm aware of could be found at <a href="https://github.com/mgechev/angular-aop">github.com/mgechev/angular-aop</a>.</p> - -<h4> -<a id="facade" class="anchor" href="#facade" aria-hidden="true"><span class="octicon octicon-link"></span></a>Facade</h4> - -<blockquote> -<p>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:</p> - -<ol> -<li><p>make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;</p></li> -<li><p>make the library more readable, for the same reason;</p></li> -<li><p>reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;</p></li> -<li><p>wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).</p></li> -</ol> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/facade.svg" alt="Facade" title="Fig. 11"></p> - -<p>There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.</p> - -<p>For example, lets take a look how we can create an <code>XMLHttpRequest</code> POST request:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> http <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">XMLHttpRequest</span>(), - url <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>/example/new<span class="pl-pds">'</span></span>, - params <span class="pl-k">=</span> encodeURIComponent(data); -http.<span class="pl-c1">open</span>(<span class="pl-s"><span class="pl-pds">"</span>POST<span class="pl-pds">"</span></span>, url, <span class="pl-c1">true</span>); - -http.<span class="pl-c1">setRequestHeader</span>(<span class="pl-s"><span class="pl-pds">"</span>Content-type<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>application/x-www-form-urlencoded<span class="pl-pds">"</span></span>); -http.<span class="pl-c1">setRequestHeader</span>(<span class="pl-s"><span class="pl-pds">"</span>Content-length<span class="pl-pds">"</span></span>, params.<span class="pl-c1">length</span>); -http.<span class="pl-c1">setRequestHeader</span>(<span class="pl-s"><span class="pl-pds">"</span>Connection<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>close<span class="pl-pds">"</span></span>); - -<span class="pl-c1">http</span>.<span class="pl-en">onreadystatechange</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - <span class="pl-k">if</span>(http.<span class="pl-c1">readyState</span> <span class="pl-k">==</span> <span class="pl-c1">4</span> <span class="pl-k">&&</span> http.<span class="pl-c1">status</span> <span class="pl-k">==</span> <span class="pl-c1">200</span>) { - <span class="pl-c1">alert</span>(http.responseText); - } -} -http.<span class="pl-c1">send</span>(params);</pre></div> - -<p>But if we want to post this data using the AngularJS' <code>$http</code> service we can:</p> - -<div class="highlight highlight-source-js"><pre>$http({ - method<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>POST<span class="pl-pds">'</span></span>, - url<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>/example/new<span class="pl-pds">'</span></span>, - data<span class="pl-k">:</span> data -}) -.then(<span class="pl-k">function</span> (<span class="pl-smi">response</span>) { - <span class="pl-c1">alert</span>(response); -});</pre></div> - -<p>or we can even:</p> - -<div class="highlight highlight-source-js"><pre>$http.post(<span class="pl-s"><span class="pl-pds">'</span>/someUrl<span class="pl-pds">'</span></span>, data) -.then(<span class="pl-k">function</span> (<span class="pl-smi">response</span>) { - <span class="pl-c1">alert</span>(response); -});</pre></div> - -<p>The second option provides pre-configured version, which creates a HTTP POST request to the given URL.</p> - -<p>Even higher level of abstraction is being created by <code>$resource</code>, which is build over the <code>$http</code> service. We will take a further look at this service in <a href="#active-record">Active Record</a> and <a href="#proxy">Proxy</a> sections.</p> - -<h4> -<a id="proxy" class="anchor" href="#proxy" aria-hidden="true"><span class="octicon octicon-link"></span></a>Proxy</h4> - -<blockquote> -<p>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/proxy.svg" alt="Proxy" title="Fig. 9"></p> - -<p>We can distinguish three different types of proxy:</p> - -<ul> -<li>Virtual Proxy</li> -<li>Remote Proxy</li> -<li>Protection Proxy</li> -</ul> - -<p>In this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.</p> - -<p>In the snippet bellow, there is a call to the <code>get</code> method of <code>$resource</code> instance, called <code>User</code>:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $resource(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), - user <span class="pl-k">=</span> User.get({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); -<span class="pl-en">console</span>.<span class="pl-c1">log</span>(user); <span class="pl-c">//{}</span></pre></div> - -<p><code>console.log</code> would outputs an empty object. Since the AJAX request, which happens behind the scene, when <code>User.get</code> is invoked, is asynchronous, we don't have the actual user when <code>console.log</code> is called. Just after <code>User.get</code> makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.</p> - -<p>How does this works with AngularJS? Well, lets consider the following snippet:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">$resource</span>) { - <span class="pl-k">var</span> User <span class="pl-k">=</span> $resource(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), - $scope.user <span class="pl-k">=</span> User.get({ id<span class="pl-k">:</span> <span class="pl-c1">42</span> }); -}</pre></div> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>user.name<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> - -<p>Initially when the snippet above executes, the property <code>user</code> of the <code>$scope</code> object will be with value an empty object (<code>{}</code>), which means that <code>user.name</code> will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next <code>$digest</code> loop AngularJS will detect change in <code>$scope.user</code>, which will lead to update of the view.</p> - -<h4> -<a id="active-record" class="anchor" href="#active-record" aria-hidden="true"><span class="octicon octicon-link"></span></a>Active Record</h4> - -<blockquote> -<p>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/active-record.svg" alt="Active Record" title="Fig. 7"></p> - -<p>AngularJS defines a service called <code>$resource</code>. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.</p> - -<p>According to the AngularJS' documentation <code>$resource</code> is:</p> - -<blockquote> -<p>A factory which creates a resource object that lets you interact with RESTful server-side data sources. -The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.</p> -</blockquote> - -<p>Here is how <code>$resource</code> could be used:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> User <span class="pl-k">=</span> $resource(<span class="pl-s"><span class="pl-pds">'</span>/users/:id<span class="pl-pds">'</span></span>), - user <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">User</span>({ - name<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, - age <span class="pl-k">:</span> <span class="pl-c1">42</span> - }); - -user.$save();</pre></div> - -<p>The call of <code>$resource</code> will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.</p> - -<p>This way we can use the constructor function and its static methods by:</p> - -<div class="highlight highlight-source-js"><pre>User.get({ userid<span class="pl-k">:</span> userid });</pre></div> - -<p>The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see <a href="#proxy">proxy</a>).</p> - -<p>You can find more details for <code>$resource</code> <a href="http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/">The magic of $resource</a> and <a href="https://docs.angularjs.org/api/ngResource/service/%24resource">AngularJS' documentation</a>.</p> - -<p>Since Martin Fowler states that</p> - -<blockquote> -<p>responsibility of the Active Record object is to take care of the communication with the databse in order to create...</p> -</blockquote> - -<p><code>$resource</code> does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as "Active Record like RESTful communication".</p> - -<h4> -<a id="intercepting-filters" class="anchor" href="#intercepting-filters" aria-hidden="true"><span class="octicon octicon-link"></span></a>Intercepting Filters</h4> - -<blockquote> -<p>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/intercepting-filters.svg" alt="Composite" title="Fig. 3"></p> - -<p>In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.</p> - -<p>In AngularJS we have the idea of the Intercepting Filters in <code>$httpProvider</code>. <code>$httpProvider</code> has an array property called <code>interceptors</code>, which contains a list of objects. Each object may have properties called: <code>request</code>, <code>response</code>, <code>requestError</code>, <code>responseError</code>.</p> - -<p><code>requestError</code> is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively <code>responseError</code> is being called when the previous <code>response</code> interceptor has thrown an error.</p> - -<p>Here is a basic example how you can add interceptors using object literal:</p> - -<div class="highlight highlight-source-js"><pre>$httpProvider.interceptors.<span class="pl-c1">push</span>(<span class="pl-k">function</span>(<span class="pl-smi">$q</span>, <span class="pl-smi">dependency1</span>, <span class="pl-smi">dependency2</span>) { - <span class="pl-k">return</span> { - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">request</span><span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">config</span>) { - <span class="pl-c">// same as above</span> - }, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">response</span><span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">response</span>) { - <span class="pl-c">// same as above</span> - } - }; -});</pre></div> - -<h3> -<a id="directives-1" class="anchor" href="#directives-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Directives</h3> - -<h4> -<a id="composite" class="anchor" href="#composite" aria-hidden="true"><span class="octicon octicon-link"></span></a>Composite</h4> - -<blockquote> -<p>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/composite.svg" alt="Composite" title="Fig. 3"></p> - -<p>According to the Gang of Four, MVC is nothing more than combination of:</p> - -<ul> -<li>Strategy</li> -<li>Composite</li> -<li>Observer</li> -</ul> - -<p>They state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.</p> - -<p>Lets look at the following example:</p> - -<div class="highlight highlight-text-html-basic"><pre><!doctype html> -<<span class="pl-ent">html</span>> - <<span class="pl-ent">head</span>> - </<span class="pl-ent">head</span>> - <<span class="pl-ent">body</span>> - <<span class="pl-ent">zippy</span> <span class="pl-e">title</span>=<span class="pl-s"><span class="pl-pds">"</span>Zippy<span class="pl-pds">"</span></span>> - Zippy! - </<span class="pl-ent">zippy</span>> - </<span class="pl-ent">body</span>> -</<span class="pl-ent">html</span>></pre></div> - -<div class="highlight highlight-source-js"><pre>myModule.directive(<span class="pl-s"><span class="pl-pds">'</span>zippy<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - <span class="pl-k">return</span> { - restrict<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>E<span class="pl-pds">'</span></span>, - template<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span><div><div class="header"></div><div class="content" ng-transclude></div></div><span class="pl-pds">'</span></span>, - <span class="pl-en">link</span><span class="pl-k">:</span> <span class="pl-k">function</span> (<span class="pl-smi">scope</span>, <span class="pl-smi">el</span>) { - el.<span class="pl-c1">find</span>(<span class="pl-s"><span class="pl-pds">'</span>.header<span class="pl-pds">'</span></span>).<span class="pl-c1">click</span>(<span class="pl-k">function</span> () { - el.<span class="pl-c1">find</span>(<span class="pl-s"><span class="pl-pds">'</span>.content<span class="pl-pds">'</span></span>).toggle(); - }); - } - } -});</pre></div> - -<p>This example defines a simple directive, which is a UI component. The defined component (called "zippy") has header and content. Click on its header toggles the visibility of the content.</p> - -<p>From the first example we can note that the whole DOM tree is a composition of elements. The root component is the <code>html</code> element, directly followed by the nested elements <code>head</code> and <code>body</code> and so on...</p> - -<p>In the second, JavaScript, example we see that the <code>template</code> property of the directive, contains markup with <code>ng-transclude</code> directive inside it. So this means that inside the directive <code>zippy</code> we have another directive called <code>ng-transclude</code>, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.</p> - -<h4> -<a id="interpreter" class="anchor" href="#interpreter" aria-hidden="true"><span class="octicon octicon-link"></span></a>Interpreter</h4> - -<blockquote> -<p>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/interpreter.svg" alt="Interpreter" title="Fig. 6"></p> - -<p>Behind its <code>$parse</code> service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. -The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:</p> - -<ul> -<li>may contain filters with UNIX like pipe syntax</li> -<li>don't throw any errors</li> -<li>don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)</li> -<li>are evaluated in given context (the context of the current <code>$scope</code>)</li> -</ul> - -<p>Inside the <code>$parse</code> service are defined two main components:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-c">//Responsible for converting given string into tokens</span> -<span class="pl-k">var</span> Lexer; -<span class="pl-c">//Responsible for parsing the tokens and evaluating the expression</span> -<span class="pl-k">var</span> Parser;</pre></div> - -<p>Once given expression have been tokenized it is cached internally, because of performance concerns.</p> - -<p>The terminal expressions in the AngularJS DSL are defined as follows:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> <span class="pl-c1">OPERATORS</span> <span class="pl-k">=</span> { - <span class="pl-c">/* jshint bitwise : false */</span> - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">null</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(){<span class="pl-k">return</span> <span class="pl-c1">null</span>;}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">true</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(){<span class="pl-k">return</span> <span class="pl-c1">true</span>;}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">false</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(){<span class="pl-k">return</span> <span class="pl-c1">false</span>;}, - <span class="pl-c1">undefined</span><span class="pl-k">:</span>noop, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">+</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){ - <span class="pl-c">//...</span> - }, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">*</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">*</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">/</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">/</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">%</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">%</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">^</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">^</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span>=<span class="pl-pds">'</span></span><span class="pl-k">:</span>noop, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">===</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>, <span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">===</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!==</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>, <span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">!==</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">==</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">==</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">!=</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en"><</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k"><</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">></span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">></span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en"><=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k"><=</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">>=</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">>=</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">&&</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">&&</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">||</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">||</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">&</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> a(self, locals)<span class="pl-k">&</span>b(self, locals);}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">|</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>,<span class="pl-smi">b</span>){<span class="pl-k">return</span> b(self, locals)(self, locals, a(self, locals));}, - <span class="pl-s"><span class="pl-pds">'</span><span class="pl-en">!</span><span class="pl-pds">'</span></span><span class="pl-k">:</span><span class="pl-k">function</span>(<span class="pl-smi">self</span>, <span class="pl-smi">locals</span>, <span class="pl-smi">a</span>){<span class="pl-k">return</span> <span class="pl-k">!</span>a(self, locals);} -};</pre></div> - -<p>We can think of the function associated with each terminal as implementation of the <code>AbstractExpression</code>'s interface.</p> - -<p>Each <code>Client</code> interprets given AngularJS expression in a specific context - specific scope.</p> - -<p>Few sample AngularJS expressions are:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-c">// toUpperCase filter is applied to the result of the expression</span> -<span class="pl-c">// (foo) ? bar : baz</span> -(foo) <span class="pl-k">?</span> bar <span class="pl-k">:</span> baz | toUpperCase</pre></div> - -<h4> -<a id="template-view" class="anchor" href="#template-view" aria-hidden="true"><span class="octicon octicon-link"></span></a>Template View</h4> - -<blockquote> -<p>Renders information into HTML by embedding markers in an HTML page.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/template-view.svg" alt="Template View" title="Fig. 8"></p> - -<p>The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.</p> - -<p>Templates are very commonly used especially in the back-end. -For example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.</p> - -<p>For JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as <code>script</code> embedded inside your view or even inlined into your JavaScript.</p> - -<p>For example:</p> - -<div class="highlight highlight-text-html-basic"><pre><span class="pl-s1"><<span class="pl-ent">script</span> <span class="pl-e">type</span>=<span class="pl-s"><span class="pl-pds">"</span>template/mustache<span class="pl-pds">"</span></span>></span> -<span class="pl-s1"> <span class="pl-k"><</span>h2<span class="pl-k">></span>Names<span class="pl-k"></</span>h2<span class="pl-k">></span></span> -<span class="pl-s1"> {{#names}}</span> -<span class="pl-s1"> <span class="pl-k"><</span>strong<span class="pl-k">></span>{{name}}<span class="pl-k"></</span>strong<span class="pl-k">></span></span> -<span class="pl-s1"> {{<span class="pl-k">/</span>names}}</span> -<span class="pl-s1"></<span class="pl-ent">script</span>></span></pre></div> - -<p>The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.</p> - -<p>For example if we evaluate the template above in the context of the following object: <code>{ names: ['foo', 'bar', 'baz'] }</code>, so we will get:</p> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">h2</span>>Names</<span class="pl-ent">h2</span>> - <<span class="pl-ent">strong</span>>foo</<span class="pl-ent">strong</span>> - <<span class="pl-ent">strong</span>>bar</<span class="pl-ent">strong</span>> - <<span class="pl-ent">strong</span>>baz</<span class="pl-ent">strong</span>></pre></div> - -<p>AngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are. -What AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.</p> - -<p>For example:</p> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">ul</span> <span class="pl-e">ng-repeat</span>=<span class="pl-s"><span class="pl-pds">"</span>name in names<span class="pl-pds">"</span></span>> - <<span class="pl-ent">li</span>>{{name}}</<span class="pl-ent">li</span>> -</<span class="pl-ent">ul</span>></pre></div> - -<p>in the context of the scope:</p> - -<div class="highlight highlight-source-js"><pre>$scope.names <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>baz<span class="pl-pds">'</span></span>];</pre></div> - -<p>will produce the same result as the one above. The main difference here is that the template is not wrapped inside a <code>script</code> tag but is HTML instead.</p> - -<h3> -<a id="scope-1" class="anchor" href="#scope-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Scope</h3> - -<h4> -<a id="observer" class="anchor" href="#observer" aria-hidden="true"><span class="octicon octicon-link"></span></a>Observer</h4> - -<blockquote> -<p>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg" alt="Observer" title="Fig. 7"></p> - -<p>There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see <a href="#scope">Scope</a>). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.</p> - -<p>Each AngularJS scope has public methods called <code>$on</code>, <code>$emit</code> and <code>$broadcast</code>. The method <code>$on</code> accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the <code>Observer</code> interface (in JavaScript the functions are first-class, so we can provide only implementation of the <code>notify</code> method):</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">ExampleCtrl</span>(<span class="pl-smi">$scope</span>) { - $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>event-name<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> <span class="pl-en">handler</span>() { - <span class="pl-c">//body</span> - }); -}</pre></div> - -<p>In this way the current scope "subscribes" to events of type <code>event-name</code>. When <code>event-name</code> is triggered in any parent or child scope of the given one, <code>handler</code> would be called.</p> - -<p>The methods <code>$emit</code> and <code>$broadcast</code> are used for triggering events respectively upwards and downwards through the scope chain. -For example:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">ExampleCtrl</span>(<span class="pl-smi">$scope</span>) { - $scope.$emit(<span class="pl-s"><span class="pl-pds">'</span>event-name<span class="pl-pds">'</span></span>, { foo<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>bar<span class="pl-pds">'</span></span> }); -}</pre></div> - -<p>The scope in the example above, triggers the event <code>event-name</code> to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event <code>event-name</code>, would be notified and their handler callback will be invoked.</p> - -<p>Analogical is the case when the method <code>$broadcast</code> is called. The only difference is that the event would be transmitted downwards - to all children scopes. -Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).</p> - -<p>In the JavaScript community this pattern is better known as publish/subscribe.</p> - -<p>For a best practice example see <a href="#observer-pattern-as-an-external-service">Observer Pattern as an External Service</a></p> - -<h4> -<a id="chain-of-responsibilities" class="anchor" href="#chain-of-responsibilities" aria-hidden="true"><span class="octicon octicon-link"></span></a>Chain of Responsibilities</h4> - -<blockquote> -<p>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/chain-of-responsibilities.svg" alt="Chain of Responsibilities" title="Fig. 5"></p> - -<p>As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their <code>$parent</code> property.</p> - -<p>When <code>$emit</code> or <code>$broadcast</code> are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:</p> - -<ul> -<li>Handle the event and pass it to the next scope in the chain</li> -<li>Handle the event and stop its propagation</li> -<li>Pass the event to the next scope in the chain without handling it</li> -<li>Stop the event propagation without handling it</li> -</ul> - -<p>In the example bellow you can see an example in which <code>ChildCtrl</code> triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in <code>ParentCtrl</code> and the one used in <code>MainCtrl</code>) are going to handle the event by logging into the console: <code>"foo received"</code>. If any of the scopes should be considered as final destination it can call the method <code>stopPropagation</code> of the event object, passed to the callback.</p> - -<div class="highlight highlight-source-js"><pre>myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>MainCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { - $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); - }); -}); - -myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>ParentCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { - $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">e</span>) { - <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>foo received<span class="pl-pds">'</span></span>); - }); -}); - -myModule.controller(<span class="pl-s"><span class="pl-pds">'</span>ChildCtrl<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$scope</span>) { - $scope.$emit(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>); -});</pre></div> - -<p>The different handlers from the UML diagram above are the different scopes, injected to the controllers.</p> - -<h4> -<a id="command" class="anchor" href="#command" aria-hidden="true"><span class="octicon octicon-link"></span></a>Command</h4> - -<blockquote> -<p>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/command.svg" alt="Command" title="Fig. 11"></p> - -<p>Before continuing with the application of the command pattern lets describe how AngularJS implements data binding.</p> - -<p>When we want to bind our model to the view we use the directives <code>ng-bind</code> (for single-way data binding) and <code>ng-model</code> (for two-way data binding). For example, if we want each change in the model <code>foo</code> to reflect the view we can:</p> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>foo<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> - -<p>Now each time we change the value of <code>foo</code> the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:</p> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">span</span> <span class="pl-e">ng-bind</span>=<span class="pl-s"><span class="pl-pds">"</span>foo + ' ' + bar | uppercase<span class="pl-pds">"</span></span>></<span class="pl-ent">span</span>></pre></div> - -<p>In the example above the value of the span will be the concatenated uppercased value of <code>foo</code> and <code>bar</code>. What happens behind the scene?</p> - -<p>Each <code>$scope</code> has method called <code>$watch</code>. When the AngularJS compiler find the directive <code>ng-bind</code> it creates a new watcher of the expression <code>foo + ' ' + bar | uppercase</code>, i.e. <code>$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });</code>. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.</p> - -<p>Here are the first a couple of lines of the implementation of <code>$watch</code>:</p> - -<div class="highlight highlight-source-js"><pre>$<span class="pl-en">watch</span><span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">watchExp</span>, <span class="pl-smi">listener</span>, <span class="pl-smi">objectEquality</span>) { - <span class="pl-k">var</span> scope <span class="pl-k">=</span> <span class="pl-v">this</span>, - get <span class="pl-k">=</span> compileToFn(watchExp, <span class="pl-s"><span class="pl-pds">'</span>watch<span class="pl-pds">'</span></span>), - array <span class="pl-k">=</span> scope.$$watchers, - watcher <span class="pl-k">=</span> { - fn<span class="pl-k">:</span> listener, - last<span class="pl-k">:</span> initWatchVal, - get<span class="pl-k">:</span> get, - exp<span class="pl-k">:</span> watchExp, - eq<span class="pl-k">:</span> <span class="pl-k">!!</span>objectEquality - }; -<span class="pl-c">//...</span></pre></div> - -<p>We can think of the <code>watcher</code> object as a command. The expression of the command is being evaluated on each <a href="https://docs.angularjs.org/api/ng/type/%24rootScope.Scope#%24digest"><code>"$digest"</code></a> loop. Once AngularJS detects change in the expression, it invokes the <code>listener</code> function. The <code>watcher</code> command encapsulates the whole information required for watching given expression and delegates the execution of the command to the <code>listener</code> (the actual receiver). We can think of the <code>$scope</code> as the command's <code>Client</code> and the <code>$digest</code> loop as the command's <code>Invoker</code>.</p> - -<h3> -<a id="controllers-1" class="anchor" href="#controllers-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Controllers</h3> - -<h4> -<a id="page-controller" class="anchor" href="#page-controller" aria-hidden="true"><span class="octicon octicon-link"></span></a>Page Controller</h4> - -<blockquote> -<p>An object that handles a request for a specific page or action on a Web site. Martin Fowler</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/page-controller.svg" alt="Page Controller" title="Fig. 8"></p> - -<p>According to <a href="#references">4</a> the page controller:</p> - -<blockquote> -<p>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code</p> -</blockquote> - -<p>Since there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the <code>$route</code> or <code>$state</code> services and the page rendering is responsibility of the directives <code>ng-view</code>/<code>ui-view</code>.</p> - -<p>Similarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.</p> - -<p>The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap. -Here is an example hierarchy between few controllers:</p> - -<div class="highlight highlight-text-html-basic"><pre><!doctype html> -<<span class="pl-ent">html</span>> - <<span class="pl-ent">head</span>> - </<span class="pl-ent">head</span>> - <<span class="pl-ent">body</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>MainCtrl<span class="pl-pds">"</span></span>> - <<span class="pl-ent">div</span> <span class="pl-e">ng-controller</span>=<span class="pl-s"><span class="pl-pds">"</span>ChildCtrl<span class="pl-pds">"</span></span>> - <<span class="pl-ent">span</span>>{{user.name}}</<span class="pl-ent">span</span>> - <<span class="pl-ent">button</span> <span class="pl-e">ng-click</span>=<span class="pl-s"><span class="pl-pds">"</span>click()<span class="pl-pds">"</span></span>>Click</<span class="pl-ent">button</span>> - </<span class="pl-ent">div</span>> - </<span class="pl-ent">body</span>> -</<span class="pl-ent">html</span>></pre></div> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">$location</span>, <span class="pl-smi">User</span>) { - <span class="pl-k">if</span> (<span class="pl-k">!</span>User.isAuthenticated()) { - $location.path(<span class="pl-s"><span class="pl-pds">'</span>/unauthenticated<span class="pl-pds">'</span></span>); - } -} - -<span class="pl-k">function</span> <span class="pl-en">ChildCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">User</span>) { - <span class="pl-c1">$scope</span>.<span class="pl-en">click</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () { - <span class="pl-c1">alert</span>(<span class="pl-s"><span class="pl-pds">'</span>You clicked me!<span class="pl-pds">'</span></span>); - }; - $scope.user <span class="pl-k">=</span> User.get(<span class="pl-c1">0</span>); -}</pre></div> - -<p>This example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.</p> - -<p>The <code>ChildCtrl</code> is responsible for handling actions such as clicking the button with label <code>"Click"</code> and exposing the model to the view, by attaching it to the scope.</p> - -<h3> -<a id="others" class="anchor" href="#others" aria-hidden="true"><span class="octicon octicon-link"></span></a>Others</h3> - -<h4> -<a id="module-pattern" class="anchor" href="#module-pattern" aria-hidden="true"><span class="octicon octicon-link"></span></a>Module Pattern</h4> - -<p>This is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.</p> - -<p>Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> Page <span class="pl-k">=</span> (<span class="pl-k">function</span> () { - - <span class="pl-k">var</span> title; - - <span class="pl-k">function</span> <span class="pl-en">setTitle</span>(<span class="pl-smi">t</span>) { - <span class="pl-c1">document</span>.<span class="pl-c1">title</span> <span class="pl-k">=</span> t; - title <span class="pl-k">=</span> t; - } - - <span class="pl-k">function</span> <span class="pl-en">getTitle</span>() { - <span class="pl-k">return</span> title; - } - - <span class="pl-k">return</span> { - setTitle<span class="pl-k">:</span> setTitle, - getTitle<span class="pl-k">:</span> getTitle - }; -}());</pre></div> - -<p>In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (<code>setTitle</code> and <code>getTitle</code>). The returned object is being assigned to the <code>Page</code> variable.</p> - -<p>In this case the user of the <code>Page</code> object doesn't has direct access to the <code>title</code> variable, which is defined inside the local scope of the IIFE.</p> - -<p>The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:</p> - -<div class="highlight highlight-source-js"><pre>app.factory(<span class="pl-s"><span class="pl-pds">'</span>foo<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> () { - - <span class="pl-k">function</span> <span class="pl-en">privateMember</span>() { - <span class="pl-c">//body...</span> - } - - <span class="pl-k">function</span> <span class="pl-en">publicMember</span>() { - <span class="pl-c">//body...</span> - privateMember(); - <span class="pl-c">//body</span> - } - - <span class="pl-k">return</span> { - publicMember<span class="pl-k">:</span> publicMember - }; -});</pre></div> - -<p>Once we want to inject <code>foo</code> inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.</p> - -<h4> -<a id="data-mapper" class="anchor" href="#data-mapper" aria-hidden="true"><span class="octicon octicon-link"></span></a>Data Mapper</h4> - -<blockquote> -<p>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.</p> -</blockquote> - -<p><img src="https://rawgit.com/mgechev/angularjs-in-patterns/master/images/data-mapper.svg" alt="Data Mapper" title="Fig. 10"></p> - -<p>As the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).</p> - -<p>Usually, if we have RESTful API <code>$resource</code> will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.</p> - -<p>For instance, lets assume we have application in which each user has:</p> - -<ul> -<li>name</li> -<li>address</li> -<li>list of friends</li> -</ul> - -<p>And our API has the methods:</p> - -<ul> -<li> -<code>GET /user/:id</code> - returns the user's name and the address of given user</li> -<li> -<code>GET /friends/:id</code> - returns the list of friends of given user</li> -</ul> - -<p>Possible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called <code>User</code>, which loads the user's friends when we request the user:</p> - -<div class="highlight highlight-source-js"><pre>app.factory(<span class="pl-s"><span class="pl-pds">'</span>User<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">$q</span>) { - - <span class="pl-k">function</span> <span class="pl-en">User</span>(<span class="pl-smi">name</span>, <span class="pl-smi">address</span>, <span class="pl-smi">friends</span>) { - <span class="pl-v">this</span>.<span class="pl-c1">name</span> <span class="pl-k">=</span> name; - <span class="pl-v">this</span>.address <span class="pl-k">=</span> address; - <span class="pl-v">this</span>.friends <span class="pl-k">=</span> friends; - } - - <span class="pl-c1">User</span>.<span class="pl-en">get</span> <span class="pl-k">=</span> <span class="pl-k">function</span> (<span class="pl-smi">params</span>) { - <span class="pl-k">var</span> user <span class="pl-k">=</span> $http.get(<span class="pl-s"><span class="pl-pds">'</span>/user/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> params.<span class="pl-c1">id</span>), - friends <span class="pl-k">=</span> $http.get(<span class="pl-s"><span class="pl-pds">'</span>/friends/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> params.<span class="pl-c1">id</span>); - $q.<span class="pl-c1">all</span>([user, friends]) - .then(<span class="pl-k">function</span> (<span class="pl-smi">user</span>, <span class="pl-smi">friends</span>) { - <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-en">User</span>(user.<span class="pl-c1">name</span>, user.address, friends); - }); - }; - <span class="pl-k">return</span> User; -});</pre></div> - -<p>This way we create pseudo-data mapper, which adapts our API according to the SPA requirements.</p> - -<p>We can use the <code>User</code> service by:</p> - -<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">MainCtrl</span>(<span class="pl-smi">$scope</span>, <span class="pl-smi">User</span>) { - User.get({ id<span class="pl-k">:</span> <span class="pl-c1">1</span> }) - .then(<span class="pl-k">function</span> (<span class="pl-smi">data</span>) { - $scope.user <span class="pl-k">=</span> data; - }); -}</pre></div> - -<p>And the following partial:</p> - -<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">div</span>> - <<span class="pl-ent">div</span>> - Name: {{user.name}} - </<span class="pl-ent">div</span>> - <<span class="pl-ent">div</span>> - Address: {{user.address}} - </<span class="pl-ent">div</span>> - <<span class="pl-ent">div</span>> - Friends with ids: - <<span class="pl-ent">ul</span>> - <<span class="pl-ent">li</span> <span class="pl-e">ng-repeat</span>=<span class="pl-s"><span class="pl-pds">"</span>friend in user.friends<span class="pl-pds">"</span></span>>{{friend}}</<span class="pl-ent">li</span>> - </<span class="pl-ent">ul</span>> - </<span class="pl-ent">div</span>> -</<span class="pl-ent">div</span>></pre></div> - -<h4> -<a id="observer-pattern-as-an-external-service" class="anchor" href="#observer-pattern-as-an-external-service" aria-hidden="true"><span class="octicon octicon-link"></span></a>Observer Pattern as an External Service</h4> - -<h5> -<a id="about" class="anchor" href="#about" aria-hidden="true"><span class="octicon octicon-link"></span></a>About</h5> - -<p>Below is an example taken from <a href="https://github.com/greglbd/angular-observer-pattern">here</a>. This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that <code>$scope.$watch</code> and more specific to a unique scope or object than $emit and $broadcast when used correctly.</p> - -<p><strong>Use Case:</strong> You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.</p> - -<h5> -<a id="controller-example" class="anchor" href="#controller-example" aria-hidden="true"><span class="octicon octicon-link"></span></a>Controller Example</h5> - -<p>Below example shows how to attach, notify and detach an event.</p> - -<div class="highlight highlight-source-js"><pre>angular.module(<span class="pl-s"><span class="pl-pds">'</span>app.controllers<span class="pl-pds">'</span></span>) - .controller(<span class="pl-s"><span class="pl-pds">'</span>ObserverExample<span class="pl-pds">'</span></span>, ObserverExample); -ObserverExample.$inject<span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>ObserverService<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$timeout<span class="pl-pds">'</span></span>]; - -<span class="pl-k">function</span> <span class="pl-en">ObserverExample</span>(<span class="pl-smi">ObserverService</span>, <span class="pl-smi">$timeout</span>) { - <span class="pl-k">var</span> vm <span class="pl-k">=</span> <span class="pl-v">this</span>; - <span class="pl-k">var</span> id <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>vm1<span class="pl-pds">'</span></span>; - - ObserverService.attach(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) - - <span class="pl-k">function</span> <span class="pl-en">callbackFunction</span>(<span class="pl-smi">params</span>){ - <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); - ObserverService.detachByEvent(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) - } - - $timeout(<span class="pl-k">function</span>(){ - ObserverService.notify(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>); - }, <span class="pl-c1">5000</span>); -}</pre></div> - -<p>Alternative way to remove event</p> - -<div class="highlight highlight-source-js"><pre>angular.module(<span class="pl-s"><span class="pl-pds">'</span>app.controllers<span class="pl-pds">'</span></span>) - .controller(<span class="pl-s"><span class="pl-pds">'</span>ObserverExample<span class="pl-pds">'</span></span>, ObserverExample); -ObserverExample.$inject<span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">'</span>ObserverService<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$timeout<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>$scope<span class="pl-pds">'</span></span>]; - -<span class="pl-k">function</span> <span class="pl-en">ObserverExample</span>(<span class="pl-smi">ObserverService</span>, <span class="pl-smi">$timeout</span>, <span class="pl-smi">$scope</span>) { - <span class="pl-k">var</span> vm <span class="pl-k">=</span> <span class="pl-v">this</span>; - <span class="pl-k">var</span> id <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>vm1<span class="pl-pds">'</span></span>; - ObserverService.attach(callbackFunction, <span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>, id) - - <span class="pl-k">function</span> <span class="pl-en">callbackFunction</span>(<span class="pl-smi">params</span>){ - <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>now i know<span class="pl-pds">'</span></span>); - } - - $timeout(<span class="pl-k">function</span>(){ - ObserverService.notify(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>); - }, <span class="pl-c1">5000</span>); - - <span class="pl-c">// Cleanup listeners when this controller is destroyed</span> - $scope.$on(<span class="pl-s"><span class="pl-pds">'</span>$destroy<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> <span class="pl-en">handler</span>() { - ObserverService.detachByEvent(<span class="pl-s"><span class="pl-pds">'</span>let_me_know<span class="pl-pds">'</span></span>) - }); -}</pre></div> - -<h2> -<a id="references" class="anchor" href="#references" aria-hidden="true"><span class="octicon octicon-link"></span></a>References</h2> - -<ol> -<li> -<a href="https://en.wikipedia.org/wiki">Wikipedia</a>. The source of all brief descriptions of the design patterns is wikipedia.</li> -<li><a href="https://docs.angularjs.org">AngularJS' documentation</a></li> -<li><a href="https://github.com/angular/angular.js">AngularJS' git repository</a></li> -<li><a href="http://msdn.microsoft.com/en-us/library/ff649595.aspx">Page Controller</a></li> -<li><a href="http://martinfowler.com/books/eaa.html">Patterns of Enterprise Application Architecture (P of EAA)</a></li> -<li><a href="http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html">Using Dependancy Injection to Avoid Singletons</a></li> -<li><a href="https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery">Why would one use the Publish/Subscribe pattern (in JS/jQuery)?</a></li> -</ol> - - <footer class="site-footer"> - <span class="site-footer-owner"><a href="https://github.com/mgechev/angularjs-in-patterns">AngularJS in Patterns</a> is maintained by <a href="https://github.com/mgechev">mgechev</a>.</span> - - <span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span> - </footer> - - </section> - - <script type="text/javascript"> - var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); - document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); - </script> - <script type="text/javascript"> - try { - var pageTracker = _gat._getTracker("UA-18060688-20"); - pageTracker._trackPageview(); - } catch(err) {} - </script> - - </body> -</html> diff --git a/index.md b/index.md new file mode 100644 index 0000000..f785107 --- /dev/null +++ b/index.md @@ -0,0 +1,1164 @@ +# AngularJS in Patterns + +<!--toc--> + +## Table of Contents + +* [Translations](#translations) +* [Abstract](#abstract) +* [Introduction](#introduction) +* [AngularJS overview](#angularjs-overview) + * [Partials](#partials) + * [Controllers](#controllers) + * [Scope](#scope) + * [Directives](#directives) + * [Filters](#filters) + * [Services](#services) +* [AngularJS Patterns](#angularjs-patterns) + * [Services](#services-1) + * [Singleton](#singleton) + * [Factory Method](#factory-method) + * [Decorator](#decorator) + * [Facade](#facade) + * [Proxy](#proxy) + * [Active Record](#active-record) + * [Intercepting Filters](#intercepting-filters) + * [Directives](#directives-1) + * [Composite](#composite) + * [Interpreter](#interpreter) + * [Template View](#template-view) + * [Scope](#scope-1) + * [Observer](#observer) + * [Chain of Responsibilities](#chain-of-responsibilities) + * [Command](#command) + * [Controller](#controller-1) + * [Page Controller](#page-controller) + * [Others](#others) + * [Module Pattern](#module-pattern) + * [Data Mapper](#data-mapper) + * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service) +* [References](#references) + +<!--endtoc--> + +## Translations + +- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter) +- [Russian Translation](http://habrahabr.ru/post/250149/) +- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko) +- [Chinese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-zh-cn.md) by [carlosliu](https://github.com/carlosliu) + +## Abstract + +One of the best ways to learn something new is to see how the things you already know are used in it. +This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. +The goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application. + +## Introduction + +The document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned. + +The last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS. + +## AngularJS overview + +AngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA). +SPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand. +Since most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are: + +- two-way data binding +- dependency injection +- separation of concerns +- testability +- abstraction + +The separation of concerns is achieved by dividing each AngularJS application into separate components, such as: + +- partials +- controllers +- directives +- services +- filters + +These components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic. + +### Partials + +The partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example). + +Initially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework. + +**Sample partial** + +```HTML +<html ng-app> + <!-- Body tag augmented with ngController directive --> + <body ng-controller="MyController"> + <input ng-model="foo" value="bar"> + <!-- Button tag with ng-click directive, and + string expression 'buttonText' + wrapped in "{{ }}" markup --> + <button ng-click="changeFoo()">{{buttonText}}</button> + <script src="angular.js"></script> + </body> +</html> +``` + +With AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked. + +### Controllers + +The AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*. + +```JavaScript +function MyController($scope) { + $scope.buttonText = 'Click me to change foo!'; + $scope.foo = 42; + + $scope.changeFoo = function () { + $scope.foo += 1; + alert('Foo changed'); + }; +} +``` + +For example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways. + +1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding. +2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`. + +All the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones. + +### Scope + +In AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial. + +Another important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype. + +Scope inheritance is illustrated in the following example: + +```HTML +<div ng-controller="BaseCtrl"> + <div id="child" ng-controller="ChildCtrl"> + <button id="parent-method" ng-click="foo()">Parent method</button> + <button ng-click="bar()">Child method</button> + </div> +</div> +``` + +```JavaScript +function BaseCtrl($scope) { + $scope.foo = function () { + alert('Base foo'); + }; +} + +function ChildCtrl($scope) { + $scope.bar = function () { + alert('Child bar'); + }; +} +``` + +With `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`. + +### Directives + +In AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations. +Each directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as: + +- template +- compile function +- link function +- etc... + +By citing the name of the directives they can be used inside the declarative partials. + +Example: + +```JavaScript +myModule.directive('alertButton', function () { + return { + template: '<button ng-transclude></button>', + scope: { + content: '@' + }, + replace: true, + restrict: 'E', + transclude: true, + link: function (scope, el) { + el.click(function () { + alert(scope.content); + }); + } + }; +}); +``` + +```HTML +<alert-button content="42">Click me</alert-button> +``` + +In the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted. + +Since the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here. + +### Filters + +The filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection. + +Here is a definition of a sample filter, which changes the given string to uppercase: + +```JavaScript +myModule.filter('uppercase', function () { + return function (str) { + return (str || '').toUpperCase(); + }; +}); +``` + +Inside a partial this filter could be used using the Unix's piping syntax: + +```HTML +<div>{{ name | uppercase }}</div> +``` + +Inside a controller the filter could be used as follows: + +```JavaScript +function MyCtrl(uppercaseFilter) { + $scope.name = uppercaseFilter('foo'); //FOO +} +``` + +### Services + +Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service. + +```JavaScript +myModule.service('Developer', function () { + this.name = 'Foo'; + this.motherLanguage = 'JavaScript'; + this.live = function () { + while (true) { + this.code(); + } + }; +}); +``` + +The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives). + +```JavaScript +function MyCtrl(Developer) { + var developer = new Developer(); + developer.live(); +} +``` + +## AngularJS Patterns + +In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components. + +In the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS. + +### Services + +#### Singleton + +>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. + +In the UML diagram bellow is illustrated the singleton design pattern. + + + +When given dependency is required by any component, AngularJS resolves it using the following algorithm: + +- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility). +- If the dependency exists AngularJS pass it as parameter to the component, which requires it. +- If the dependency does not exists: + - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency. + - AngularJS caches it inside the hash map mentioned above. + - AngularJS passes it as parameter to the component, which requires it. + +We can take better look at the AngularJS' source code, which implements the method `getService`: + +```JavaScript +function getService(serviceName) { + if (cache.hasOwnProperty(serviceName)) { + if (cache[serviceName] === INSTANTIATING) { + throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); + } + return cache[serviceName]; + } else { + try { + path.unshift(serviceName); + cache[serviceName] = INSTANTIATING; + return cache[serviceName] = factory(serviceName); + } catch (err) { + if (cache[serviceName] === INSTANTIATING) { + delete cache[serviceName]; + } + throw err; + } finally { + path.shift(); + } + } +} +``` + +We can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`). + +This way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation: + +- It improves the testability of your source code +- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy) + +For further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered. + +#### Factory Method + +>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor. + + + +Lets consider the following snippet: + +```JavaScript +myModule.config(function ($provide) { + $provide.provider('foo', function () { + var baz = 42; + return { + //Factory method + $get: function (bar) { + var baz = bar.baz(); + return { + baz: baz + }; + } + }; + }); +}); + +``` + +In the code above we use the `config` callback in order to define new "provider". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way. + +Each service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance. + +We can dig a little bit deeper in AngularJS' implementation: + +```JavaScript +//... + +createInternalInjector(instanceCache, function(servicename) { + var provider = providerInjector.get(servicename + providerSuffix); + return instanceInjector.invoke(provider.$get, provider, undefined, servicename); +}, strictDi)); + +//... + +function invoke(fn, self, locals, serviceName){ + if (typeof locals === 'string') { + serviceName = locals; + locals = null; + } + + var args = [], + $inject = annotate(fn, strictDi, serviceName), + length, i, + key; + + for(i = 0, length = $inject.length; i < length; i++) { + key = $inject[i]; + if (typeof key !== 'string') { + throw $injectorMinErr('itkn', + 'Incorrect injection token! Expected service name as string, got {0}', key); + } + args.push( + locals && locals.hasOwnProperty(key) + ? locals[key] + : getService(key) + ); + } + if (!fn.$inject) { + // this means that we must be an array. + fn = fn[length]; + } + + return fn.apply(self, args); +} +``` + +From the example above we can notice how the `$get` method is actually used: + +```JavaScript +instanceInjector.invoke(provider.$get, provider, undefined, servicename) +``` + +The snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`. + +If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product". + +There are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like: + +- The most appropriate moment, when the component needs to be instantiated +- Resolving all the dependencies required by the component +- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers) + +#### Decorator + +>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. + + + +AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create "wrapper" of any service you have previously defined or used by a third-party: + +```JavaScript +myModule.controller('MainCtrl', function (foo) { + foo.bar(); +}); + +myModule.factory('foo', function () { + return { + bar: function () { + console.log('I\'m bar'); + }, + baz: function () { + console.log('I\'m baz'); + } + }; +}); + +myModule.config(function ($provide) { + $provide.decorator('foo', function ($delegate) { + var barBackup = $delegate.bar; + $delegate.bar = function () { + console.log('Decorated'); + barBackup.apply($delegate, arguments); + }; + return $delegate; + }); +}); +``` +The example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `"foo"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function. +We decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context. + +Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop). + +#### Facade + +>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can: + +>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks; + +>2. make the library more readable, for the same reason; + +>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system; + +>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs). + + + +There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade. + +For example, lets take a look how we can create an `XMLHttpRequest` POST request: + +```JavaScript +var http = new XMLHttpRequest(), + url = '/example/new', + params = encodeURIComponent(data); +http.open("POST", url, true); + +http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); +http.setRequestHeader("Content-length", params.length); +http.setRequestHeader("Connection", "close"); + +http.onreadystatechange = function () { + if(http.readyState == 4 && http.status == 200) { + alert(http.responseText); + } +} +http.send(params); +``` +But if we want to post this data using the AngularJS' `$http` service we can: + +```JavaScript +$http({ + method: 'POST', + url: '/example/new', + data: data +}) +.then(function (response) { + alert(response); +}); +``` +or we can even: + +```JavaScript +$http.post('/someUrl', data) +.then(function (response) { + alert(response); +}); +``` +The second option provides pre-configured version, which creates a HTTP POST request to the given URL. + +Even higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections. + +#### Proxy + +>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. + + + +We can distinguish three different types of proxy: + +- Virtual Proxy +- Remote Proxy +- Protection Proxy + +In this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy. + +In the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`: + +```JavaScript +var User = $resource('/users/:id'), + user = User.get({ id: 42 }); +console.log(user); //{} +``` + +`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server. + +How does this works with AngularJS? Well, lets consider the following snippet: + +```JavaScript +function MainCtrl($scope, $resource) { + var User = $resource('/users/:id'), + $scope.user = User.get({ id: 42 }); +} +``` + +```html +<span ng-bind="user.name"></span> +``` +Initially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view. + +#### Active Record + +>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication. + + + +AngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core. + +According to the AngularJS' documentation `$resource` is: + +>A factory which creates a resource object that lets you interact with RESTful server-side data sources. +>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service. + +Here is how `$resource` could be used: + +```JavaScript +var User = $resource('/users/:id'), + user = new User({ + name: 'foo', + age : 42 + }); + +user.$save(); +``` + +The call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations. + +This way we can use the constructor function and its static methods by: + +```JavaScript +User.get({ userid: userid }); +``` + +The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)). + +You can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource). + +Since Martin Fowler states that + +> responsibility of the Active Record object is to take care of the communication with the databse in order to create... + +`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as "Active Record like RESTful communication". + +#### Intercepting Filters + +>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request. + + + +In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one. + +In AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`. + +`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error. + +Here is a basic example how you can add interceptors using object literal: + +```JavaScript +$httpProvider.interceptors.push(function($q, dependency1, dependency2) { + return { + 'request': function(config) { + // same as above + }, + 'response': function(response) { + // same as above + } + }; +}); +``` + +### Directives + +#### Composite + +>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. + + + +According to the Gang of Four, MVC is nothing more than combination of: + +- Strategy +- Composite +- Observer + +They state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied. + +Lets look at the following example: + +```HTML +<!doctype html> +<html> + <head> + </head> + <body> + <zippy title="Zippy"> + Zippy! + </zippy> + </body> +</html> +``` + +```JavaScript +myModule.directive('zippy', function () { + return { + restrict: 'E', + template: '<div><div class="header"></div><div class="content" ng-transclude></div></div>', + link: function (scope, el) { + el.find('.header').click(function () { + el.find('.content').toggle(); + }); + } + } +}); +``` + +This example defines a simple directive, which is a UI component. The defined component (called "zippy") has header and content. Click on its header toggles the visibility of the content. + +From the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on... + +In the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node. + +#### Interpreter + +>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence. + + + +Behind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. +The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions: + +- may contain filters with UNIX like pipe syntax +- don't throw any errors +- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator) +- are evaluated in given context (the context of the current `$scope`) + +Inside the `$parse` service are defined two main components: + +```JavaScript +//Responsible for converting given string into tokens +var Lexer; +//Responsible for parsing the tokens and evaluating the expression +var Parser; +``` + +Once given expression have been tokenized it is cached internally, because of performance concerns. + +The terminal expressions in the AngularJS DSL are defined as follows: + +```JavaScript +var OPERATORS = { + /* jshint bitwise : false */ + 'null':function(){return null;}, + 'true':function(){return true;}, + 'false':function(){return false;}, + undefined:noop, + '+':function(self, locals, a,b){ + //... + }, + '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);}, + '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);}, + '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);}, + '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);}, + '=':noop, + '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);}, + '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);}, + '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);}, + '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);}, + '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);}, + '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);}, + '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);}, + '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);}, + '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);}, + '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);}, + '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);}, + '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));}, + '!':function(self, locals, a){return !a(self, locals);} +}; +``` + +We can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface. + +Each `Client` interprets given AngularJS expression in a specific context - specific scope. + +Few sample AngularJS expressions are: + +```JavaScript +// toUpperCase filter is applied to the result of the expression +// (foo) ? bar : baz +(foo) ? bar : baz | toUpperCase +``` + +#### Template View + +> Renders information into HTML by embedding markers in an HTML page. + + + +The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format. + +Templates are very commonly used especially in the back-end. +For example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages. + +For JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript. + +For example: + +```html +<script type="template/mustache"> + <h2>Names</h2> + {{#names}} + <strong>{{name}}</strong> + {{/names}} +</script> +``` + +The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value. + +For example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get: + +```html +<h2>Names</h2> + <strong>foo</strong> + <strong>bar</strong> + <strong>baz</strong> +``` + +AngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are. +What AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope. + +For example: + +```html +<ul ng-repeat="name in names"> + <li>{{name}}</li> +</ul> +``` + +in the context of the scope: + +```javascript +$scope.names = ['foo', 'bar', 'baz']; +``` + +will produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead. + + +### Scope + +#### Observer + +>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. + + + +There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes. + +Each AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method): + +```JavaScript +function ExampleCtrl($scope) { + $scope.$on('event-name', function handler() { + //body + }); +} +``` + +In this way the current scope "subscribes" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called. + +The methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain. +For example: + +```JavaScript +function ExampleCtrl($scope) { + $scope.$emit('event-name', { foo: 'bar' }); +} +``` + +The scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked. + +Analogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes. +Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event). + +In the JavaScript community this pattern is better known as publish/subscribe. + +For a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service) + +#### Chain of Responsibilities + +>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain. + + + +As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property. + +When `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may: + +- Handle the event and pass it to the next scope in the chain +- Handle the event and stop its propagation +- Pass the event to the next scope in the chain without handling it +- Stop the event propagation without handling it + +In the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `"foo received"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback. + +```JavaScript +myModule.controller('MainCtrl', function ($scope) { + $scope.$on('foo', function () { + console.log('foo received'); + }); +}); + +myModule.controller('ParentCtrl', function ($scope) { + $scope.$on('foo', function (e) { + console.log('foo received'); + }); +}); + +myModule.controller('ChildCtrl', function ($scope) { + $scope.$emit('foo'); +}); +``` + +The different handlers from the UML diagram above are the different scopes, injected to the controllers. + +#### Command + +>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters. + + + +Before continuing with the application of the command pattern lets describe how AngularJS implements data binding. + +When we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can: + +```html +<span ng-bind="foo"></span> +``` + +Now each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like: + +```html +<span ng-bind="foo + ' ' + bar | uppercase"></span> +``` + +In the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene? + +Each `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span. + +Here are the first a couple of lines of the implementation of `$watch`: + +```javascript +$watch: function(watchExp, listener, objectEquality) { + var scope = this, + get = compileToFn(watchExp, 'watch'), + array = scope.$$watchers, + watcher = { + fn: listener, + last: initWatchVal, + get: get, + exp: watchExp, + eq: !!objectEquality + }; +//... +``` + +We can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`"$digest"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`. + +### Controllers + +#### Page Controller + +>An object that handles a request for a specific page or action on a Web site. Martin Fowler + + + +According to [4](#references) the page controller: + +>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code + +Since there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`. + +Similarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers. + +The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap. +Here is an example hierarchy between few controllers: + +```HTML +<!doctype html> +<html> + <head> + </head> + <body ng-controller="MainCtrl"> + <div ng-controller="ChildCtrl"> + <span>{{user.name}}</span> + <button ng-click="click()">Click</button> + </div> + </body> +</html> +``` + +```JavaScript +function MainCtrl($scope, $location, User) { + if (!User.isAuthenticated()) { + $location.path('/unauthenticated'); + } +} + +function ChildCtrl($scope, User) { + $scope.click = function () { + alert('You clicked me!'); + }; + $scope.user = User.get(0); +} +``` + +This example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction. + +The `ChildCtrl` is responsible for handling actions such as clicking the button with label `"Click"` and exposing the model to the view, by attaching it to the scope. + +### Others + +#### Module Pattern + +This is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy. + +Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module: + +```javascript +var Page = (function () { + + var title; + + function setTitle(t) { + document.title = t; + title = t; + } + + function getTitle() { + return title; + } + + return { + setTitle: setTitle, + getTitle: getTitle + }; +}()); +``` + +In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable. + +In this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE. + +The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy: + +```javascript +app.factory('foo', function () { + + function privateMember() { + //body... + } + + function publicMember() { + //body... + privateMember(); + //body + } + + return { + publicMember: publicMember + }; +}); +``` + +Once we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library. + +#### Data Mapper + +>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself. + + + +As the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.). + +Usually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end. + +For instance, lets assume we have application in which each user has: + +- name +- address +- list of friends + +And our API has the methods: + +- `GET /user/:id` - returns the user's name and the address of given user +- `GET /friends/:id` - returns the list of friends of given user + +Possible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user: + +```javascript +app.factory('User', function ($q) { + + function User(name, address, friends) { + this.name = name; + this.address = address; + this.friends = friends; + } + + User.get = function (params) { + var user = $http.get('/user/' + params.id), + friends = $http.get('/friends/' + params.id); + $q.all([user, friends]) + .then(function (user, friends) { + return new User(user.name, user.address, friends); + }); + }; + return User; +}); +``` + +This way we create pseudo-data mapper, which adapts our API according to the SPA requirements. + +We can use the `User` service by: + +```javascript +function MainCtrl($scope, User) { + User.get({ id: 1 }) + .then(function (data) { + $scope.user = data; + }); +} +``` + +And the following partial: + +```html +<div> + <div> + Name: {{user.name}} + </div> + <div> + Address: {{user.address}} + </div> + <div> + Friends with ids: + <ul> + <li ng-repeat="friend in user.friends">{{friend}}</li> + </ul> + </div> +</div> +``` + +#### Observer Pattern as an External Service + +##### About + +Below is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly. + +**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway. + +##### Controller Example + +Below example shows how to attach, notify and detach an event. + +```javascript +angular.module('app.controllers') + .controller('ObserverExample', ObserverExample); +ObserverExample.$inject= ['ObserverService', '$timeout']; + +function ObserverExample(ObserverService, $timeout) { + var vm = this; + var id = 'vm1'; + + ObserverService.attach(callbackFunction, 'let_me_know', id) + + function callbackFunction(params){ + console.log('now i know'); + ObserverService.detachByEvent('let_me_know') + } + + $timeout(function(){ + ObserverService.notify('let_me_know'); + }, 5000); +} +``` +Alternative way to remove event + +```javascript +angular.module('app.controllers') + .controller('ObserverExample', ObserverExample); +ObserverExample.$inject= ['ObserverService', '$timeout', '$scope']; + +function ObserverExample(ObserverService, $timeout, $scope) { + var vm = this; + var id = 'vm1'; + ObserverService.attach(callbackFunction, 'let_me_know', id) + + function callbackFunction(params){ + console.log('now i know'); + } + + $timeout(function(){ + ObserverService.notify('let_me_know'); + }, 5000); + + // Cleanup listeners when this controller is destroyed + $scope.$on('$destroy', function handler() { + ObserverService.detachByEvent('let_me_know') + }); +} +``` + +## References + +1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia. +2. [AngularJS' documentation](https://docs.angularjs.org) +3. [AngularJS' git repository](https://github.com/angular/angular.js) +4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx) +5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html) +6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) +7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery) diff --git a/params.json b/params.json deleted file mode 100644 index a888b12..0000000 --- a/params.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"AngularJS in Patterns","tagline":"\"AngularJS in Patterns\" provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any AngularJS application.","body":"# AngularJS in Patterns\r\n\r\n<!--toc-->\r\n\r\n## Table of Contents\r\n\r\n* [Translations](#translations)\r\n* [Abstract](#abstract)\r\n* [Introduction](#introduction)\r\n* [AngularJS overview](#angularjs-overview)\r\n * [Partials](#partials)\r\n * [Controllers](#controllers)\r\n * [Scope](#scope)\r\n * [Directives](#directives)\r\n * [Filters](#filters)\r\n * [Services](#services)\r\n* [AngularJS Patterns](#angularjs-patterns)\r\n * [Services](#services-1)\r\n * [Singleton](#singleton)\r\n * [Factory Method](#factory-method)\r\n * [Decorator](#decorator)\r\n * [Facade](#facade)\r\n * [Proxy](#proxy)\r\n * [Active Record](#active-record)\r\n * [Intercepting Filters](#intercepting-filters)\r\n * [Directives](#directives-1)\r\n * [Composite](#composite)\r\n * [Interpreter](#interpreter)\r\n * [Template View](#template-view)\r\n * [Scope](#scope-1)\r\n * [Observer](#observer)\r\n * [Chain of Responsibilities](#chain-of-responsibilities)\r\n * [Command](#command)\r\n * [Controller](#controller-1)\r\n * [Page Controller](#page-controller)\r\n * [Others](#others)\r\n * [Module Pattern](#module-pattern)\r\n * [Data Mapper](#data-mapper)\r\n * [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n* [References](#references)\r\n\r\n<!--endtoc-->\r\n\r\n## Translations\r\n\r\n- [Japanese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-ja-jp.md) by [morizotter](https://twitter.com/morizotter)\r\n- [Russian Translation](http://habrahabr.ru/post/250149/)\r\n- [French Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-fr-fr.md) by [manekinekko](https://github.com/manekinekko)\r\n- [Chinese Translation](https://github.com/mgechev/angularjs-in-patterns/blob/master/i18n/README-zh-cn.md) by [carlosliu](https://github.com/carlosliu)\r\n\r\n## Abstract\r\n\r\nOne of the best ways to learn something new is to see how the things you already know are used in it.\r\nThis document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns.\r\nThe goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application.\r\n\r\n## Introduction\r\n\r\nThe document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned.\r\n\r\nThe last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS.\r\n\r\n## AngularJS overview\r\n\r\nAngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA).\r\nSPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand.\r\nSince most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are:\r\n\r\n- two-way data binding\r\n- dependency injection\r\n- separation of concerns\r\n- testability\r\n- abstraction\r\n\r\nThe separation of concerns is achieved by dividing each AngularJS application into separate components, such as:\r\n\r\n- partials\r\n- controllers\r\n- directives\r\n- services\r\n- filters\r\n\r\nThese components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic.\r\n\r\n### Partials\r\n\r\nThe partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example).\r\n\r\nInitially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework.\r\n\r\n**Sample partial**\r\n\r\n```HTML\r\n<html ng-app>\r\n <!-- Body tag augmented with ngController directive -->\r\n <body ng-controller=\"MyController\">\r\n <input ng-model=\"foo\" value=\"bar\">\r\n <!-- Button tag with ng-click directive, and\r\n string expression 'buttonText'\r\n wrapped in \"{{ }}\" markup -->\r\n <button ng-click=\"changeFoo()\">{{buttonText}}</button>\r\n <script src=\"angular.js\"></script>\r\n </body>\r\n</html>\r\n```\r\n\r\nWith AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked.\r\n\r\n### Controllers\r\n\r\nThe AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*.\r\n\r\n```JavaScript\r\nfunction MyController($scope) {\r\n $scope.buttonText = 'Click me to change foo!';\r\n $scope.foo = 42;\r\n\r\n $scope.changeFoo = function () {\r\n $scope.foo += 1;\r\n alert('Foo changed');\r\n };\r\n}\r\n```\r\n\r\nFor example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways.\r\n\r\n1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding.\r\n2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`.\r\n\r\nAll the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones.\r\n\r\n### Scope\r\n\r\nIn AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial.\r\n\r\nAnother important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype.\r\n\r\nScope inheritance is illustrated in the following example:\r\n\r\n```HTML\r\n<div ng-controller=\"BaseCtrl\">\r\n <div id=\"child\" ng-controller=\"ChildCtrl\">\r\n <button id=\"parent-method\" ng-click=\"foo()\">Parent method</button>\r\n <button ng-click=\"bar()\">Child method</button>\r\n </div>\r\n</div>\r\n```\r\n\r\n```JavaScript\r\nfunction BaseCtrl($scope) {\r\n $scope.foo = function () {\r\n alert('Base foo');\r\n };\r\n}\r\n\r\nfunction ChildCtrl($scope) {\r\n $scope.bar = function () {\r\n alert('Child bar');\r\n };\r\n}\r\n```\r\n\r\nWith `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`.\r\n\r\n### Directives\r\n\r\nIn AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new directive or consider refactoring of already existing one, which could handle the required DOM manipulations.\r\nEach directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as:\r\n\r\n- template\r\n- compile function\r\n- link function\r\n- etc...\r\n\r\nBy citing the name of the directives they can be used inside the declarative partials.\r\n\r\nExample:\r\n\r\n```JavaScript\r\nmyModule.directive('alertButton', function () {\r\n return {\r\n template: '<button ng-transclude></button>',\r\n scope: {\r\n content: '@'\r\n },\r\n replace: true,\r\n restrict: 'E',\r\n transclude: true,\r\n link: function (scope, el) {\r\n el.click(function () {\r\n alert(scope.content);\r\n });\r\n }\r\n };\r\n});\r\n```\r\n\r\n```HTML\r\n<alert-button content=\"42\">Click me</alert-button>\r\n```\r\n\r\nIn the example above the tag `<alert-button></alert-button>` will be replaced button element. When the user clicks on the button the string `42` will be alerted.\r\n\r\nSince the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here.\r\n\r\n### Filters\r\n\r\nThe filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection.\r\n\r\nHere is a definition of a sample filter, which changes the given string to uppercase:\r\n\r\n```JavaScript\r\nmyModule.filter('uppercase', function () {\r\n return function (str) {\r\n return (str || '').toUpperCase();\r\n };\r\n});\r\n```\r\n\r\nInside a partial this filter could be used using the Unix's piping syntax:\r\n\r\n```HTML\r\n<div>{{ name | uppercase }}</div>\r\n```\r\n\r\nInside a controller the filter could be used as follows:\r\n\r\n```JavaScript\r\nfunction MyCtrl(uppercaseFilter) {\r\n $scope.name = uppercaseFilter('foo'); //FOO\r\n}\r\n```\r\n\r\n### Services\r\n\r\nEvery piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too \"fat\" the repetitive code should be placed inside a service.\r\n\r\n```JavaScript\r\nmyModule.service('Developer', function () {\r\n this.name = 'Foo';\r\n this.motherLanguage = 'JavaScript';\r\n this.live = function () {\r\n while (true) {\r\n this.code();\r\n }\r\n };\r\n});\r\n```\r\n\r\nThe service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives).\r\n\r\n```JavaScript\r\nfunction MyCtrl(Developer) {\r\n var developer = new Developer();\r\n developer.live();\r\n}\r\n```\r\n\r\n## AngularJS Patterns\r\n\r\nIn the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components.\r\n\r\nIn the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS.\r\n\r\n### Services\r\n\r\n#### Singleton\r\n\r\n>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.\r\n\r\nIn the UML diagram bellow is illustrated the singleton design pattern.\r\n\r\n\r\n\r\nWhen given dependency is required by any component, AngularJS resolves it using the following algorithm:\r\n\r\n- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility).\r\n- If the dependency exists AngularJS pass it as parameter to the component, which requires it.\r\n- If the dependency does not exists:\r\n - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency.\r\n - AngularJS caches it inside the hash map mentioned above.\r\n - AngularJS passes it as parameter to the component, which requires it.\r\n\r\nWe can take better look at the AngularJS' source code, which implements the method `getService`:\r\n\r\n```JavaScript\r\nfunction getService(serviceName) {\r\n if (cache.hasOwnProperty(serviceName)) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));\r\n }\r\n return cache[serviceName];\r\n } else {\r\n try {\r\n path.unshift(serviceName);\r\n cache[serviceName] = INSTANTIATING;\r\n return cache[serviceName] = factory(serviceName);\r\n } catch (err) {\r\n if (cache[serviceName] === INSTANTIATING) {\r\n delete cache[serviceName];\r\n }\r\n throw err;\r\n } finally {\r\n path.shift();\r\n }\r\n }\r\n}\r\n```\r\n\r\nWe can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`).\r\n\r\nThis way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation:\r\n\r\n- It improves the testability of your source code\r\n- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy)\r\n\r\nFor further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered.\r\n\r\n#### Factory Method\r\n\r\n>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor.\r\n\r\n\r\n\r\nLets consider the following snippet:\r\n\r\n```JavaScript\r\nmyModule.config(function ($provide) {\r\n $provide.provider('foo', function () {\r\n var baz = 42;\r\n return {\r\n //Factory method\r\n $get: function (bar) {\r\n var baz = bar.baz();\r\n return {\r\n baz: baz\r\n };\r\n }\r\n };\r\n });\r\n});\r\n\r\n```\r\n\r\nIn the code above we use the `config` callback in order to define new \"provider\". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way.\r\n\r\nEach service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance.\r\n\r\nWe can dig a little bit deeper in AngularJS' implementation:\r\n\r\n```JavaScript\r\n//...\r\n\r\ncreateInternalInjector(instanceCache, function(servicename) {\r\n var provider = providerInjector.get(servicename + providerSuffix);\r\n return instanceInjector.invoke(provider.$get, provider, undefined, servicename);\r\n}, strictDi));\r\n\r\n//...\r\n\r\nfunction invoke(fn, self, locals, serviceName){\r\n if (typeof locals === 'string') {\r\n serviceName = locals;\r\n locals = null;\r\n }\r\n\r\n var args = [],\r\n $inject = annotate(fn, strictDi, serviceName),\r\n length, i,\r\n key;\r\n\r\n for(i = 0, length = $inject.length; i < length; i++) {\r\n key = $inject[i];\r\n if (typeof key !== 'string') {\r\n throw $injectorMinErr('itkn',\r\n 'Incorrect injection token! Expected service name as string, got {0}', key);\r\n }\r\n args.push(\r\n locals && locals.hasOwnProperty(key)\r\n ? locals[key]\r\n : getService(key)\r\n );\r\n }\r\n if (!fn.$inject) {\r\n // this means that we must be an array.\r\n fn = fn[length];\r\n }\r\n\r\n return fn.apply(self, args);\r\n}\r\n```\r\n\r\nFrom the example above we can notice how the `$get` method is actually used:\r\n\r\n```JavaScript\r\ninstanceInjector.invoke(provider.$get, provider, undefined, servicename)\r\n```\r\n\r\nThe snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`.\r\n\r\nIf we think in terms of the UML diagram above we can call the provider a \"ConcreteCreator\" and the actual component, which is being created a \"Product\".\r\n\r\nThere are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like:\r\n\r\n- The most appropriate moment, when the component needs to be instantiated\r\n- Resolving all the dependencies required by the component\r\n- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers)\r\n\r\n#### Decorator\r\n\r\n>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.\r\n\r\n\r\n\r\nAngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create \"wrapper\" of any service you have previously defined or used by a third-party:\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function (foo) {\r\n foo.bar();\r\n});\r\n\r\nmyModule.factory('foo', function () {\r\n return {\r\n bar: function () {\r\n console.log('I\\'m bar');\r\n },\r\n baz: function () {\r\n console.log('I\\'m baz');\r\n }\r\n };\r\n});\r\n\r\nmyModule.config(function ($provide) {\r\n $provide.decorator('foo', function ($delegate) {\r\n var barBackup = $delegate.bar;\r\n $delegate.bar = function () {\r\n console.log('Decorated');\r\n barBackup.apply($delegate, arguments);\r\n };\r\n return $delegate;\r\n });\r\n});\r\n```\r\nThe example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `\"foo\"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function.\r\nWe decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context.\r\n\r\nUsing this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop).\r\n\r\n#### Facade\r\n\r\n>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:\r\n\r\n>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;\r\n\r\n>2. make the library more readable, for the same reason;\r\n\r\n>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;\r\n\r\n>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).\r\n\r\n\r\n\r\nThere are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade.\r\n\r\nFor example, lets take a look how we can create an `XMLHttpRequest` POST request:\r\n\r\n```JavaScript\r\nvar http = new XMLHttpRequest(),\r\n url = '/example/new',\r\n params = encodeURIComponent(data);\r\nhttp.open(\"POST\", url, true);\r\n\r\nhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\r\nhttp.setRequestHeader(\"Content-length\", params.length);\r\nhttp.setRequestHeader(\"Connection\", \"close\");\r\n\r\nhttp.onreadystatechange = function () {\r\n if(http.readyState == 4 && http.status == 200) {\r\n alert(http.responseText);\r\n }\r\n}\r\nhttp.send(params);\r\n```\r\nBut if we want to post this data using the AngularJS' `$http` service we can:\r\n\r\n```JavaScript\r\n$http({\r\n method: 'POST',\r\n url: '/example/new',\r\n data: data\r\n})\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nor we can even:\r\n\r\n```JavaScript\r\n$http.post('/someUrl', data)\r\n.then(function (response) {\r\n alert(response);\r\n});\r\n```\r\nThe second option provides pre-configured version, which creates a HTTP POST request to the given URL.\r\n\r\nEven higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections.\r\n\r\n#### Proxy\r\n\r\n>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.\r\n\r\n\r\n\r\nWe can distinguish three different types of proxy:\r\n\r\n- Virtual Proxy\r\n- Remote Proxy\r\n- Protection Proxy\r\n\r\nIn this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy.\r\n\r\nIn the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = User.get({ id: 42 });\r\nconsole.log(user); //{}\r\n```\r\n\r\n`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server.\r\n\r\nHow does this works with AngularJS? Well, lets consider the following snippet:\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $resource) {\r\n var User = $resource('/users/:id'),\r\n $scope.user = User.get({ id: 42 });\r\n}\r\n```\r\n\r\n```html\r\n<span ng-bind=\"user.name\"></span>\r\n```\r\nInitially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view.\r\n\r\n#### Active Record\r\n\r\n>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication.\r\n\r\n\r\n\r\nAngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core.\r\n\r\nAccording to the AngularJS' documentation `$resource` is:\r\n\r\n>A factory which creates a resource object that lets you interact with RESTful server-side data sources.\r\n>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.\r\n\r\nHere is how `$resource` could be used:\r\n\r\n```JavaScript\r\nvar User = $resource('/users/:id'),\r\n user = new User({\r\n name: 'foo',\r\n age : 42\r\n });\r\n\r\nuser.$save();\r\n```\r\n\r\nThe call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations.\r\n\r\nThis way we can use the constructor function and its static methods by:\r\n\r\n```JavaScript\r\nUser.get({ userid: userid });\r\n```\r\n\r\nThe code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)).\r\n\r\nYou can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource).\r\n\r\nSince Martin Fowler states that\r\n\r\n> responsibility of the Active Record object is to take care of the communication with the databse in order to create...\r\n\r\n`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as \"Active Record like RESTful communication\".\r\n\r\n#### Intercepting Filters\r\n\r\n>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request.\r\n\r\n\r\n\r\nIn some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one.\r\n\r\nIn AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`.\r\n\r\n`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error.\r\n\r\nHere is a basic example how you can add interceptors using object literal:\r\n\r\n```JavaScript\r\n$httpProvider.interceptors.push(function($q, dependency1, dependency2) {\r\n return {\r\n 'request': function(config) {\r\n // same as above\r\n },\r\n 'response': function(response) {\r\n // same as above\r\n }\r\n };\r\n});\r\n```\r\n\r\n### Directives\r\n\r\n#### Composite\r\n\r\n>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to \"compose\" objects into tree structures to represent part-whole hierarchies.\r\n\r\n\r\n\r\nAccording to the Gang of Four, MVC is nothing more than combination of:\r\n\r\n- Strategy\r\n- Composite\r\n- Observer\r\n\r\nThey state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied.\r\n\r\nLets look at the following example:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body>\r\n <zippy title=\"Zippy\">\r\n Zippy!\r\n </zippy>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nmyModule.directive('zippy', function () {\r\n return {\r\n restrict: 'E',\r\n template: '<div><div class=\"header\"></div><div class=\"content\" ng-transclude></div></div>',\r\n link: function (scope, el) {\r\n el.find('.header').click(function () {\r\n el.find('.content').toggle();\r\n });\r\n }\r\n }\r\n});\r\n```\r\n\r\nThis example defines a simple directive, which is a UI component. The defined component (called \"zippy\") has header and content. Click on its header toggles the visibility of the content.\r\n\r\nFrom the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on...\r\n\r\nIn the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node.\r\n\r\n#### Interpreter\r\n\r\n>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.\r\n\r\n\r\n\r\nBehind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript.\r\nThe main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions:\r\n\r\n- may contain filters with UNIX like pipe syntax\r\n- don't throw any errors\r\n- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator)\r\n- are evaluated in given context (the context of the current `$scope`)\r\n\r\nInside the `$parse` service are defined two main components:\r\n\r\n```JavaScript\r\n//Responsible for converting given string into tokens\r\nvar Lexer;\r\n//Responsible for parsing the tokens and evaluating the expression\r\nvar Parser;\r\n```\r\n\r\nOnce given expression have been tokenized it is cached internally, because of performance concerns.\r\n\r\nThe terminal expressions in the AngularJS DSL are defined as follows:\r\n\r\n```JavaScript\r\nvar OPERATORS = {\r\n /* jshint bitwise : false */\r\n 'null':function(){return null;},\r\n 'true':function(){return true;},\r\n 'false':function(){return false;},\r\n undefined:noop,\r\n '+':function(self, locals, a,b){\r\n //...\r\n },\r\n '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},\r\n '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},\r\n '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},\r\n '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},\r\n '=':noop,\r\n '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},\r\n '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},\r\n '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},\r\n '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},\r\n '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},\r\n '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},\r\n '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},\r\n '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},\r\n '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},\r\n '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},\r\n '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},\r\n '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},\r\n '!':function(self, locals, a){return !a(self, locals);}\r\n};\r\n```\r\n\r\nWe can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface.\r\n\r\nEach `Client` interprets given AngularJS expression in a specific context - specific scope.\r\n\r\nFew sample AngularJS expressions are:\r\n\r\n```JavaScript\r\n// toUpperCase filter is applied to the result of the expression\r\n// (foo) ? bar : baz\r\n(foo) ? bar : baz | toUpperCase\r\n```\r\n\r\n#### Template View\r\n\r\n> Renders information into HTML by embedding markers in an HTML page.\r\n\r\n\r\n\r\nThe dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format.\r\n\r\nTemplates are very commonly used especially in the back-end.\r\nFor example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages.\r\n\r\nFor JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript.\r\n\r\nFor example:\r\n\r\n```html\r\n<script type=\"template/mustache\">\r\n <h2>Names</h2>\r\n {{#names}}\r\n <strong>{{name}}</strong>\r\n {{/names}}\r\n</script>\r\n```\r\n\r\nThe template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value.\r\n\r\nFor example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get:\r\n\r\n```html\r\n<h2>Names</h2>\r\n <strong>foo</strong>\r\n <strong>bar</strong>\r\n <strong>baz</strong>\r\n```\r\n\r\nAngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are.\r\nWhat AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope.\r\n\r\nFor example:\r\n\r\n```html\r\n<ul ng-repeat=\"name in names\">\r\n <li>{{name}}</li>\r\n</ul>\r\n```\r\n\r\nin the context of the scope:\r\n\r\n```javascript\r\n$scope.names = ['foo', 'bar', 'baz'];\r\n```\r\n\r\nwill produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead.\r\n\r\n\r\n### Scope\r\n\r\n#### Observer\r\n\r\n>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.\r\n\r\n\r\n\r\nThere are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes.\r\n\r\nEach AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method):\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$on('event-name', function handler() {\r\n //body\r\n });\r\n}\r\n```\r\n\r\nIn this way the current scope \"subscribes\" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called.\r\n\r\nThe methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain.\r\nFor example:\r\n\r\n```JavaScript\r\nfunction ExampleCtrl($scope) {\r\n $scope.$emit('event-name', { foo: 'bar' });\r\n}\r\n```\r\n\r\nThe scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked.\r\n\r\nAnalogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes.\r\nEach scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event).\r\n\r\nIn the JavaScript community this pattern is better known as publish/subscribe.\r\n\r\nFor a best practice example see [Observer Pattern as an External Service](#observer-pattern-as-an-external-service)\r\n\r\n#### Chain of Responsibilities\r\n\r\n>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.\r\n\r\n\r\n\r\nAs stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are \"isolated\", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.\r\n\r\nWhen `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may:\r\n\r\n- Handle the event and pass it to the next scope in the chain\r\n- Handle the event and stop its propagation\r\n- Pass the event to the next scope in the chain without handling it\r\n- Stop the event propagation without handling it\r\n\r\nIn the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `\"foo received\"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback.\r\n\r\n```JavaScript\r\nmyModule.controller('MainCtrl', function ($scope) {\r\n $scope.$on('foo', function () {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ParentCtrl', function ($scope) {\r\n $scope.$on('foo', function (e) {\r\n console.log('foo received');\r\n });\r\n});\r\n\r\nmyModule.controller('ChildCtrl', function ($scope) {\r\n $scope.$emit('foo');\r\n});\r\n```\r\n\r\nThe different handlers from the UML diagram above are the different scopes, injected to the controllers.\r\n\r\n#### Command\r\n\r\n>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.\r\n\r\n\r\n\r\nBefore continuing with the application of the command pattern lets describe how AngularJS implements data binding.\r\n\r\nWhen we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can:\r\n\r\n```html\r\n<span ng-bind=\"foo\"></span>\r\n```\r\n\r\nNow each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like:\r\n\r\n```html\r\n<span ng-bind=\"foo + ' ' + bar | uppercase\"></span>\r\n```\r\n\r\nIn the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene?\r\n\r\nEach `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch(\"foo + ' ' + bar | uppercase\", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span.\r\n\r\nHere are the first a couple of lines of the implementation of `$watch`:\r\n\r\n```javascript\r\n$watch: function(watchExp, listener, objectEquality) {\r\n var scope = this,\r\n get = compileToFn(watchExp, 'watch'),\r\n array = scope.$$watchers,\r\n watcher = {\r\n fn: listener,\r\n last: initWatchVal,\r\n get: get,\r\n exp: watchExp,\r\n eq: !!objectEquality\r\n };\r\n//...\r\n```\r\n\r\nWe can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`\"$digest\"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`.\r\n\r\n### Controllers\r\n\r\n#### Page Controller\r\n\r\n>An object that handles a request for a specific page or action on a Web site. Martin Fowler\r\n\r\n\r\n\r\nAccording to [4](#references) the page controller:\r\n\r\n>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code\r\n\r\nSince there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.\r\n\r\nSimilarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.\r\n\r\nThe controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.\r\nHere is an example hierarchy between few controllers:\r\n\r\n```HTML\r\n<!doctype html>\r\n<html>\r\n <head>\r\n </head>\r\n <body ng-controller=\"MainCtrl\">\r\n <div ng-controller=\"ChildCtrl\">\r\n <span>{{user.name}}</span>\r\n <button ng-click=\"click()\">Click</button>\r\n </div>\r\n </body>\r\n</html>\r\n```\r\n\r\n```JavaScript\r\nfunction MainCtrl($scope, $location, User) {\r\n if (!User.isAuthenticated()) {\r\n $location.path('/unauthenticated');\r\n }\r\n}\r\n\r\nfunction ChildCtrl($scope, User) {\r\n $scope.click = function () {\r\n alert('You clicked me!');\r\n };\r\n $scope.user = User.get(0);\r\n}\r\n```\r\n\r\nThis example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.\r\n\r\nThe `ChildCtrl` is responsible for handling actions such as clicking the button with label `\"Click\"` and exposing the model to the view, by attaching it to the scope.\r\n\r\n### Others\r\n\r\n#### Module Pattern\r\n\r\nThis is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.\r\n\r\nUsing the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:\r\n\r\n```javascript\r\nvar Page = (function () {\r\n\r\n var title;\r\n\r\n function setTitle(t) {\r\n document.title = t;\r\n title = t;\r\n }\r\n\r\n function getTitle() {\r\n return title;\r\n }\r\n\r\n return {\r\n setTitle: setTitle,\r\n getTitle: getTitle\r\n };\r\n}());\r\n```\r\n\r\nIn the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.\r\n\r\nIn this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE.\r\n\r\nThe module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy:\r\n\r\n```javascript\r\napp.factory('foo', function () {\r\n\r\n function privateMember() {\r\n //body...\r\n }\r\n\r\n function publicMember() {\r\n //body...\r\n privateMember();\r\n //body\r\n }\r\n\r\n return {\r\n publicMember: publicMember\r\n };\r\n});\r\n```\r\n\r\nOnce we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.\r\n\r\n#### Data Mapper\r\n\r\n>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.\r\n\r\n\r\n\r\nAs the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).\r\n\r\nUsually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.\r\n\r\nFor instance, lets assume we have application in which each user has:\r\n\r\n- name\r\n- address\r\n- list of friends\r\n\r\nAnd our API has the methods:\r\n\r\n- `GET /user/:id` - returns the user's name and the address of given user\r\n- `GET /friends/:id` - returns the list of friends of given user\r\n\r\nPossible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:\r\n\r\n```javascript\r\napp.factory('User', function ($q) {\r\n\r\n function User(name, address, friends) {\r\n this.name = name;\r\n this.address = address;\r\n this.friends = friends;\r\n }\r\n\r\n User.get = function (params) {\r\n var user = $http.get('/user/' + params.id),\r\n friends = $http.get('/friends/' + params.id);\r\n $q.all([user, friends])\r\n .then(function (user, friends) {\r\n return new User(user.name, user.address, friends);\r\n });\r\n };\r\n return User;\r\n});\r\n```\r\n\r\nThis way we create pseudo-data mapper, which adapts our API according to the SPA requirements.\r\n\r\nWe can use the `User` service by:\r\n\r\n```javascript\r\nfunction MainCtrl($scope, User) {\r\n User.get({ id: 1 })\r\n .then(function (data) {\r\n $scope.user = data;\r\n });\r\n}\r\n```\r\n\r\nAnd the following partial:\r\n\r\n```html\r\n<div>\r\n <div>\r\n Name: {{user.name}}\r\n </div>\r\n <div>\r\n Address: {{user.address}}\r\n </div>\r\n <div>\r\n Friends with ids:\r\n <ul>\r\n <li ng-repeat=\"friend in user.friends\">{{friend}}</li>\r\n </ul>\r\n </div>\r\n</div>\r\n```\r\n\r\n#### Observer Pattern as an External Service\r\n\r\n##### About\r\n\r\nBelow is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.\r\n\r\n**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.\r\n\r\n##### Controller Example\r\n\r\nBelow example shows how to attach, notify and detach an event.\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout) {\r\n var vm = this;\r\n var id = 'vm1';\r\n\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n ObserverService.detachByEvent('let_me_know')\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n}\r\n```\r\nAlternative way to remove event\r\n\r\n```javascript\r\nangular.module('app.controllers')\r\n .controller('ObserverExample', ObserverExample);\r\nObserverExample.$inject= ['ObserverService', '$timeout', '$scope'];\r\n\r\nfunction ObserverExample(ObserverService, $timeout, $scope) {\r\n var vm = this;\r\n var id = 'vm1';\r\n ObserverService.attach(callbackFunction, 'let_me_know', id)\r\n\r\n function callbackFunction(params){\r\n console.log('now i know');\r\n }\r\n\r\n $timeout(function(){\r\n ObserverService.notify('let_me_know');\r\n }, 5000);\r\n\r\n // Cleanup listeners when this controller is destroyed\r\n $scope.$on('$destroy', function handler() {\r\n ObserverService.detachByEvent('let_me_know')\r\n });\r\n}\r\n```\r\n\r\n## References\r\n\r\n1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia.\r\n2. [AngularJS' documentation](https://docs.angularjs.org)\r\n3. [AngularJS' git repository](https://github.com/angular/angular.js)\r\n4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx)\r\n5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html)\r\n6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html)\r\n7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery)\r\n","google":"UA-18060688-20","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 91bb7e9b7e7bea41aabb92af6365b886e684728d Mon Sep 17 00:00:00 2001 From: Minko Gechev <mgechev@gmail.com> Date: Sun, 8 Jan 2017 22:01:51 +0200 Subject: [PATCH 18/19] Update From dde981ccb0646ff1804d407c55b10091d37df83a Mon Sep 17 00:00:00 2001 From: Minko Gechev <mgechev@gmail.com> Date: Tue, 10 Jan 2017 15:41:30 +0200 Subject: [PATCH 19/19] Set theme jekyll-theme-cayman