using the angularjs package for sublime text

21
1| Page Using the AngularJS Package for Sublime Text AngularJS Sublime Text Package features include: Code completion of core AngularJS directives (ng-model, ng-repeat, etc.) Code completion for key AngularJS objects and components such as directive Support for custom directive code completion Enhanced functionality within AngularJS HTML templates defined in a page Ability to customize the attributes, element directives, etc. AngularJS How to Code Quickly with Sublime Text Editor Do the following and enjoy the Angular ride much more than ever: Download and install Sublime Text Editor from http://www.sublimetext.com/. Download Angular Sublime package (zip file) developed by Angular-UI team from this page:https://github.com/angular-ui/AngularJS-sublime-package. This page consists of greater details on further customizing the Sublime for AngularJS. Unzip and name the root package (angularjs-sublime-packager-master) as “AngularJS”. Make sure you have all the files just within this package. Copy AngularJS folder. Open Sublime Text Editor and paste “AngularJS” folder by opening “Preferences > Browse Packages” Paste some of the following configuration (JSON format) by opening the “Preferences > Settings – User”. The file would look like following: // Settings in here override those in "Default/Preferences.sublime-settings", and // are overridden in turn by file type specific settings. { "auto_complete_selector": "source - comment, meta.tag - punctuation.definition.tag.begin", "auto_complete_triggers": [ { "characters": "ng-controller=\"*", "selector": "punctuation.definition.string" } ] } Close Sublime and open it again. And, try your AngularJS hello world program. You could check the preferences related with AngularJS and customize appropriately as shown in following screenshot. Reference: http://vitalflux.com/angularjs-code-quickly-sublime-text-editor http://java.dzone.com/articles/angularjs-how-code-quickly

Upload: runtime-exception

Post on 16-Dec-2015

259 views

Category:

Documents


3 download

TRANSCRIPT

  • 1 | P a g e

    Using the AngularJS Package for Sublime Text

    AngularJS Sublime Text Package features include: Code completion of core AngularJS directives (ng-model, ng-repeat, etc.) Code completion for key AngularJS objects and components such as directive Support for custom directive code completion Enhanced functionality within AngularJS HTML templates defined in a page Ability to customize the attributes, element directives, etc.

    AngularJS How to Code Quickly with Sublime Text EditorDo the following and enjoy the Angular ride much more than ever:

    Download and install Sublime Text Editor from http://www.sublimetext.com/. Download Angular Sublime package (zip file) developed by Angular-UI team from this

    page:https://github.com/angular-ui/AngularJS-sublime-package. This page consists of greater details onfurther customizing the Sublime for AngularJS.

    Unzip and name the root package (angularjs-sublime-packager-master) as AngularJS. Make sure you haveall the files just within this package.

    Copy AngularJS folder. Open Sublime Text Editor and paste AngularJS folder by opening Preferences > Browse Packages Paste some of the following configuration (JSON format) by opening the Preferences > Settings User.

    The file would look like following:// Settings in here override those in "Default/Preferences.sublime-settings", and// are overridden in turn by file type specific settings.{

    "auto_complete_selector": "source - comment, meta.tag - punctuation.definition.tag.begin","auto_complete_triggers":

    [{"characters": "ng-controller=\"*","selector": "punctuation.definition.string"}

    ]}

    Close Sublime and open it again. And, try your AngularJS hello world program. You could check thepreferences related with AngularJS and customize appropriately as shown in following screenshot.

    Reference:http://vitalflux.com/angularjs-code-quickly-sublime-text-editorhttp://java.dzone.com/articles/angularjs-how-code-quickly

  • 2 | P a g e

    BasicsAngularJS is a client-side web application framework that reimagines HTML.

    Let that sink in. If you are an experienced web developer, you have probably already compared Angular to familiarJavaScript frameworks and libraries, such as jQuery, Knockout, Backbone,Ember, and possibly even React.Similarly, if you know something about GUI programming, you may have tried to relate Angular to Model ViewController (MVC) or Model View ViewModel (MVVM). These impulses are natural, but they can cloud yourunderstanding of Angular. For this chapter only, I would ask you to let go of thinking of Angular as a JavaScriptframework. Hold off for a moment on trying to understand how it works under the hood. Take Angular at face value.Experience it just as a powerful set of extensions to HTML.

    We'll start with three fundamental Angular constructs: expressions, directives, and scopes. However, before we getinto the examples, let's quickly review how to get Angular working in a web page. (Or, skip ahead to start the sectionon expressions.)

    Set upWhere do you get Angular? While you can download it from the official site, loading Angular into your pagefrom Google Hosted Libraries (a CDN) is both convenient and likely to perform well. The live examples in this pagedo so by including the script tag shown below within the head element.

    After including the Angular library file, you need to let Angular know which part of the HTML document it shouldmanage. Remember that Angular is HTML-oriented rather than JavaScript-oriented. Rather than writing someJavaScript to load it, we instead add some non-standard HTML that Angular will recognize. This is a special ng-app attribute that we can add to any element in the DOM. For the examples in this chapter, we will place it onthe body element, as shown below. By choosing to put it on the body or html element, we give our Angularapplication control over our entire page. You can pick a narrower scope if you like, which allows you to use anotherframework alongside Angular, or even load additional Angular applications. This makes sense for a more traditional,document-oriented web site in which client-side code is contained within isolated widgets, rather than a single-page application (SPA).

    With this magic attribute, we now have Angular working in our page. Now then, what can we do with it?

    ExpressionsBe warned: If you have been trained in the doctrine of unobtrusive JavaScript, the following examples may set offalarm bells, as Angular's first order of business is to allow you to mix JavaScript-like expressions into your HTML.Angular expressions can be almost any simple, valid JavaScript, although flow control structures like loops andsome other things are not allowed. Please suspend judgement as we explore the boundaries of what is permitted(but not necessarily in good taste) through some old-fashioned experimentation.

    Let's start by adding two numbers. Like all of the code in this book, the listing below is a live editor that lets youmodify the example. You may change any part of it. The output is rendered within aniframe sandbox and will beinstantly updated.The number {{3 + 4}}.Go ahead, replace 3 + 4 in the live example above with a different math expression. See if you can find somethingthat Angular won't or can't handle. (When Angular fails to process an expression, it either outputs the original string,or in the case of some errors, nothing at all.)

  • 3 | P a g e

    The double curly brackets are template delimiters. If you are familiar with Mustache or perhapsHandlebars, thenyou have seen double curly brackets used this way before. One way to think of Angular is just as a reallysophisticated templating library. It treats everything within the element you marked with ng-app as a template thatis compiled when your page loads, and re-rendered whenever there are changes to data. (Don't worry if you areunfamiliar with templating; we'll cover the basics of it later.)How about testing the equality of two values? Sure, we can do that too.

    Are strings and numbers equal? {{'2' == 2}}The result is correct for JavaScript. If you're surprised by it, quickly review JavaScript comparison operators, thenchange == to === in the example above. (Strict comparisons are better, right?)Here is an example that concatenates strings and also demonstrates that we have access to standard libraryfunctions such as String's toUpperCase instance method.{{"Angular" + "js".toUpperCase()}}Are you getting the feeling that you can do whatever you want inside expressions? Not so fast, partner.

    {{alert("Hello world")}}You definitely can't use alert. Nor can you access most of JavaScript's global objects, such Math,Number, Date,and so on.Try replacing alert("Hello world") in the example above with parseInt("1"), Date.now(),Number.NaN,and Math.random(). If no output is shown, Angular has refused to parse the expression.Although Angular limits what you can do in expressions, I suspect you will exhaust your tolerance for mixing codeand markup before you feel constrained by the framework. Let's probe the limits in any case. Do you think we canassign variables?

    {{a = 1; a + a}}It works. But try adding the var keyword before the variable name. Do you get an error? If you see the raw expressionincluding the delimiters in the output, you have caused an error. Do not feel bad. Breaking things is a great way tolearn.So is experimentation. I do not know if a variable assigned inside one set of delimiters can be used within another.Why not try?

    {{a = 1}} remains {{a}}Yes, it works. What if you move the initialization of the variable to the second expression? Go ahead, try it. Does itwork? Can you guess a possible reason why?

    Ok, expressions support assignment. What about the ternary operator?

    There {{count = 1; (count == 1 ? "is " : "are ") + count}} of them.Fortunately that works as well, since the ternary operator offers a concise syntax that can be really useful intemplates.

    Now, what about the increment operator (++)? Can we use that?{{a = 1; ++a}}Apparently not. Still, what about a for loop? We'll avoid idiomatic use of var and the increment operator, since we'vealready disqualified those.{{for (i = 0; i < 10; i = i + 1) {i}}}

  • 4 | P a g e

    The for loop is not executed. It produces a syntax error that you should be able to see in your browser's console.But there is nothing invalid in the JavaScript in this statement. In the browser's console, paste the statement for (i= 0; i < 10; i = i + 1) {i};. It should evaluate to 9. Go ahead, try it. So, we have hit a few boundaries: Angularexpressions are not JavaScript. Theexpression language does not support conditionals, loops, or throwing errors.We have likely pushed things far enough with expressions. Personally, I am ok with some JavaScript in my markupwhen it is concise and view related, so I appreciate the relatively permissive nature of Angular expressions. However,any more than just a little JavaScript within a template rapidly becomes unsightly and confusing. Fortunately,expressions merely play a supporting role in Angular. We should never feel the need to place too much code withinthem.

    The real key to Angular's mind-blowing productivity is the directive.

    DirectivesDirectives are the heart and soul of Angular. I recommend that you start out by thinking of them simply as customHTML. Most of the time, directives appear in the form of attributes that can be used on normal, familiar elements.The built-in directives that come pre-packaged with Angular generally start with an ng- prefix, which is a referenceto the ng in Angular. There are also countless third-party directives now available. There must be a directive forthat should be your standard reaction when you see verbose JavaScript within an Angular expression.We have already used a directive. Do you remember it? To get Angular working in the live examples in this chapter,we added ng-app to the page's body element. (Go back for a look.) In this case, we used the directive withoutpassing any arguments to it. When you pass arguments to a directive, you simply use ="", just as you would witha normal HTML attribute. For example, we could pass in the name of application with ng-app="myApp". (Theapplication name is actually the name of a module, an important part of Angular's architecture that is covered inthe Modules chapter.)

    ng-bindSome directives accept and parse string expressions. (You can verify the parameters for a built-in directive by visitingits API documentation.) For example, the ng-bind directive simply renders expressions, just like the double curlybrackets that we used in the previous section. This is what it looks like.The number .While this simple usage results in exactly the same output as the first example above, there is an importantdifference in the behavior of ng-bind: The content of the element to which you apply ng-bind is replaced when thetemplate is rendered. Therefore, the preferred technique is to use ng-bindbut to not put anything inside the element,with the result that during the brief moment before Angular replaces your raw template, nothing is shown. This canbe advantageous. Depending on the user's environment and the size and behavior of your Angular application,there can be actually be a delay that allows users to see the double curly bracket delimiters and expressions in youruncompiled page content. Using ng-bind on empty elements avoids this.At some point as your Angular application grows in size, you may want to address these flicker issues at a higherlevel by hiding most or all of your content until Angular has loaded. This is easy to do with the ng-cloak directive.See why there must be a directive for that is the right mindset?

    ng-initRemember how we initialized a variable in an expression, just to see if it would work? Well, you guessed it: Thereis also a directive for that. With ng-init, you can initialize variables for use anywhere within the element to whichit is applied. {{sum + 1}} is more than

    Using semicolons to delimit statements, you can initialize as many variables as you like.

    There are {{count}} {{units}} in a{{collection}}.

  • 5 | P a g e

    At some point, you may find it better to organize your variables as the properties of an object.

    There are {{time.count}}{{time.units}} in a {{time.collection}}. Arrays are also useful.

    {{months[3]}} follows {{months[2]}} in{{months}}. It is important to be careful about property names when coding Angular templates. You can probably spot theerrors in the template below by looking, but don't expect any help from Angular. It quietly tolerates all propertyaccess errors, including nested properties on nonexistent parents and out-of-bounds array access.

    "{{typo.sentence.words[0]}}","{{paragraph.typo.words[1]}}", "{{paragraph.sentence.typo[2]}}", "{{paragraph.sentence.words[3]}}".

    My personal wish is that instead of being so tolerant, Angular had employed something like CoffeeScript'swonderfully concise existential operator (?) to make these silent access failures an option rather than the rule.Given Angular's permissiveness so far, do you think we are permitted to declare functions withinng-init? Whatwould you guess? There are {{count()}} months in a year. No, the function expression above is not allowed. While trying to process the argument to ng-init, Angular throwsa $parse:syntax error that you can see in the JavaScript console of your browser. The correct place to declarefunctions for use in Angular expressions is within a controller, as we will learn in theupcoming Controllers chapter. In fact, controllers are the proper place to prepare application data for the view.The ng-init directive, while fun to play with in this chapter, is actually intended for aliasing variables as a way tocope with variable shadowing, as we shall see in the Collections chapter.

    ng-non-bindableBy the way, if you need to shield some part of your document from Angular's processing, adding ng-non-bindable toan element will exclude its contents from compilation. {{2 * 2}} is the same as ? Remove the ng-non-bindable directive from the example above to see what happens.

    ng-showIt is time to explore something more than simply rendering expressions. For starters, how can we conditionallydisplay or hide an HTML element?

    I can offer some advice from my own experience of how not to do this with Angular. The very first time I usedAngular, I needed to hide a form after the user successfully submitted it. Inside a controller that I had created tohandle the user action, I added a call to jQuery.hide(). It worked, of course, and if you are learning Angular withinthe context of a fast-paced project, sometimes you need to be pragmatic. However, there must be a directive forthat would have served me well. Indeed there is. Two directives, in fact: ng-hide and ng-show.We can demonstrate the use of both at the same time.

    The secret code is0123not for you to see

  • 6 | P a g e

    Change true to false in the example to see what happens. Since Angular is always watching for changes, you cantoggle the value of a variable like authorized anywhere you have access to it, and the view will be updated for theuser.At this point, it is probably time to go a bit more in depth about variables like authorized and understand whatthey actually are.

    ScopesScopes provide a single source of truth within your application. The idea is that no matter in how many places youdisplay some data in your view layer, you should only have to change it in one place (a scope property), and thechange should automatically propagate throughout the view.

    Since this automatic rendering and re-rendering requires infrastructure, the most notable thing about the JavaScriptobjects that you set on Angular scopes is how ordinary they appear. You may be familiar with the concept of plainold domain model objects. The original is the Plain Old Java Object, or POJO. When the POJO idea was firstexplained by Martin Fowler, he meant the basic, ordinary objects directly provided by the core language runtime,as opposed to unwieldy domain model objects that inherit special capabilities from a framework superclass.However, the term wasextended to mean objects that appear plain but which are transparently enhanced by aframework with special runtime capabilities, typically persistence.

    The objects attached to Angular scopes are JavaScript POJOs, since Angular applies sophisticated change detectionat runtime in order to propagate changes. When the Object.observe language feature makes it into mainstreamJavaScript, Angular may truly become a plain old JavaScriptframework.

    We have already seen scope properties in this chapter. Remember the variables that we initialized inside expressionsand using ng-init in the examples above? These are are all scope properties. Remember when I asked you to addthe var keyword to an expression? Using var is prohibited because what I previously called variables (my apologiesfor the deception) are in fact properties on a scope object that is automatically created for us behind the scenes.The next chapter will cover scopes in greater depth. Right now let's get into some hands-on examples thatdemonstrate how we use scope properties.

    Two-way bindingSo far, we have seen examples of one-way binding, in which scope data is dynamically updated in the view. Thingsreally get exciting when you use HTML controls to modify this data. Together with the view updates, this is referredto as two-way binding.

    For a primitive first example, we can use the ng-click directive to modify a boolean property.

    The secret code is0123not for you to see

    The argument to ng-click can be any expression. Although it is a versatile directive that is not limited to acting uponscope properties, the inline code for flipping a boolean works well since it is so simple. But how do you bind moresophisticated inputs and data types?

    ng-model

  • 7 | P a g e

    It seems like every introduction to Angular demonstrates data binding with a text input and a string property.Finally, it's our turn.

    is bound to"".Type something in the box!This example is the poster child for two-way binding. When we add the ng-model directive to theHTML input element, Angular wraps the default HTML control in its own input directive.What more can we do? Well, we can always use ng-init to provide an initial property value.

    is bound to"".Change it!Let's try some other input types. Here is a checkbox.

    is bound to.Change it!The value bound to a checkbox can be a string rather than a boolean if you set the ng-true-valueand ng-false-value parameters.

    is bound to"".Change it!Angular's select directive works as you might expect. Notice that it ignores the selected attribute on thefirst option. Remove the ng-init directive and you will see that selected still has no effect.

    YesNoMaybe

    is bound to"".Change it!With just three options, the last example might work better as a group of radio buttons. No problem, let's changeit.

    Yes No Maybeis bound to"".Change it!

    You now have some real-world experience manipulating scope data using Angular directives. There are manymore built-in directives, and we will explore a number of them in the upcoming chapters.

  • 8 | P a g e

    ConclusionAt the beginning of this chapter, I asked you not to think of Angular as a JavaScript framework, but rather as a setof extensions to HTML. As Angular creator Miko Hevery recounts in this fascinating interview, Angular wasoriginally conceived as a radically more productive way for front-end developers to enhance web pages. TheJavaScript framework came later.

    Central to Angular's original strategy is the premise that a declarative programming style is the best fit for rapidGUI development. However, rather than asking developers to invest in a new domain-specific language (DSL) forweb development, as was attempted with MXML and XUL, Angular builds upon the widespread familiarity ofHTML.

    So much for the vision. For the moment at least, Angular is virtually never used without custom JavaScript. Real-world Angular applications almost always make use of controllers, services, androuters, as well assupporting modules, dependency injection, and Ajax infrastructure, all of which is covered in this book. However,the productivity promise of Angular is still best realized when a web developer is able to work mainly in thedeclarative space, with a degree of confidence that there must be a directive for that. Writing customdirectives to fill the gaps is one of the more challenging areas of Angular, which is why this chapter tries to startyour Angular journey with the end in mind. Now that you understand that the ultimate goal is productivity-boosting extensions to HTML, rather than just writing JavaScript code within a framework, you are betterprepared to dive into the details.

  • 9 | P a g e

    ControllersIn the previous chapter, Basics, I asked you to rein in your JavaScript horses while we explored Angular's originalvalue proposition, which is to provide the front-end developer with powerful extensions to HTML. Of course, theAngular story doesn't end there, and customizing behavior via JavaScript is the norm for virtually every Angularproject. If you spent the first chapter wondering when we would get to some real coding, your patience will now berewarded. It's time to write JavaScript.

    The most common way to augment an Angular view using JavaScript is with a controller. The easiest way to writea controller is as a plain old constructor function. In order to understand exactly what is happening, let's start outwith a very simple controller. This is not even hello world. It does absolutely nothing.

    This is our controller.

    function EmptyController() {

    };

    Rendering the scope properties prepared by a controller requires the Angular library file. The fragment below willbe copied inside the head element of each rendered example.

    In the HTML document, we must configure our Angular application to load the app module. In the previouschapter, Basics, I showed how to add the ng-app directive to an element in order to tell Angular which part of yourdocument it should process. Look at the usage of ng-app in the example below. Can you pick out the new addition?

    Controllers can be defined as constructor functions declared on the global scope, and that is the approach we willuse in this chapter. This simple form of controller was supported by default in Angular versions up to 1.3 to facilitatedeveloper onboarding, but it now requires the following configuration, which involves creating a named applicationmodule. The details of usingangular.module will be explained in the upcoming chapters Modules, DependencyInjection, andServices. For now, just treat the example below as some required boilerplate.angular.module('app', []);angular.module('app').config(['$controllerProvider', function($controllerProvider) {$controllerProvider.allowGlobals();

    }]);

    Now that we have that out of the way, let's try out our noop controller.

    ng-controllerAs usual, the way to do it is with a directive. The ng-controller directive finds and invokes the controller functionpassed to it by name.

  • 10 | P a g e

    As you may have expected, invoking this empty controller function does nothing. Now then, what are thesecontrollers? How do we use them?

    Constructing the modelThe conceptual overview in the official guide states that the controller's job is to expose variables and functionalityto expressions and directives. The functionality refers to callback functions. We will get to those in a little while.Right now, let's talk about initializing variables, or preparing the model.

    Keeping in mind that the Angular model is just ordinary JavaScript that can be reached through anexpression's scope, preparing the model is a piece of cake. Ordinary JavaScript? Sure, we can write ordinaryJavaScript. Let's add a simple string property to our empty controller.

    function MessageController() {

    this.message = "This is a model.";

    }Simple, right? Are we done? Does the assignment above create a model? Yes? No?

    The answer is almost. When we can reach the message property through the view's scope, then it will be a model.One way to accomplish this is to expose the entire controller as a property on the scope. This may sound like a bigdeal, but if you know the secret syntax, it is easy to do.

    Controller as propertyNameAs explained in the API documentation for ng-controller, you can pass a Controller as propertyName expression asthe ng-controller argument. Please note that you need Angular version 1.2 or later to use this feature.

    {{controller.message}}

    Look at that, we have just prepared model data using a controller.

    Although the method of attaching properties directly to the this reference is straightforward, exposing the entirecontroller to the view gives the misleading impression that the controller is part of the model, when traditionally,the controller's role is just to prepare the model. Testing and debugging is often easier when you limit access toonly what a client needs and nothing more. Also, this approach adds noise to the view code, since all propertiesmust be accessed through the reference to the controller. View code is typically the most critical area of a webapplication for noise; it's the first place where we are likely to have trouble understanding intentions at a glance.Finally, controllers work hand-in-hand with the scope, so for instructional purposes it will be helpful to see areference to the scope and have fine-grained control over it. With this control, we can explicitly expose only whatwe want to the view. Therefore, this book will prefer the controller style that explicitly manages the scope object.The first question, then, is how we can get a reference to this scope object. Do we create it using thenew operator?Do we request it from somewhere?

  • 11 | P a g e

    Dependency injectionNo, we get it via dependency injection. You also may have noticed that I have not exhibited code that instantiatesa controller, such as var controller = new MessageController();. Who is creating the controllers used in the views,then?Angular is, of course. Angular is an Inversion of Control container that manages the lifecycle ofapplication components. When a new controller or other component is needed, Angular constructs one. This savesus work, but more importantly, it makes it possible for Angular to inject resources, or dependencies, into ourcomponents.

    $scopeAs a component that is managed by the dependency injection framework, our controller just needs a parameternamed $scope added to it. The naming of this parameter is critical. So critical, in fact, that if you minify yourJavaScript source code as part of your build, you will break the dependency injection mechanism. (Don't worry,there is a workaround, explained in the Dependency Injectionchapter.)

    function MessageController($scope) {

    $scope.message = "This is a model.";

    }

    By adding the $scope parameter to our constructor function, we inform Angular that we want a reference to theview's scope. Really, could this be any easier? Now, instead of declaring the messageproperty on this (thecontroller), we declare it directly on the scope.In the template, we remove the as controller from the ng-controller directive. Theexpressioncontroller.message becomes just message, which is now the only property that we have attached to thescope.

    {{message}}

    While both methods of exposing model data work, this book will mostly use the method that injects theexplicit $scope reference. Dependency injection is an integral part of using angular, as you shall see, so we mayas well get some familiarity with it.

    Model-view-controllerThe definition of a controller from the official guide also mentions exposing functionality to the view. Before wemove on to this area, I think it may be worth taking a moment to discuss how Angular controllers differ a bit fromthe classical MVC pattern. (Or, skip the academics.)

    According to the Wikipedia entry for model-view-controller (MVC), a controller mediates input, converting it tocommands for the model or view. However, it can be hard to understand the commands for the model or viewpart in the context of Angular, since Angular's version of the MVC model is radically simplified, with anemicmodels that as a rule contain no logic. In Angular, at least these days, the prevailing approach is to place all business

  • 12 | P a g e

    logic, also known as domain logic, inside the controller. In other words, Angular applications trend toward skinnymodels and fat controllers.

    If you are familiar with patterns such as rich domain model and Skinny Controller, Fat Model, I would expect youto find Angular's approach to be a step backward. I think it's probably just a question of priorities. In client-sideprogramming today, the critical distinction is between declarative, DOM-oriented view code on one side, andimperative, data-driven JavaScript code handling business logic and application infrastructure on the other. That'sa big win, and I'm happy that frameworks such as Angular are focused on it. Someday perhaps, separating businesslogic from the other responsibilities of controllers will become more of a priority, and we will see a trend towardricher models.

    FunctionsLet's write a controller that exposes a very basic function, simply to test that we can somehow invoke this functionfrom the view. As you may recall from the previous chapter, Angular did not permit us to declare and exposefunctions within the view.

    The controller below assigns a basic function to a property on the scope.

    function CountController($scope) {

    $scope.count = function() { return 12; }

    }

    Invoking the function within an expression is similar to normal JavaScript: We just use parentheses

    There are {{count()}} months in a year.

    Note that the function is not simply invoked and forgotten, but is in fact bound to the model. What does that mean?Well, Angular's binding infrastructure is something that you have probably begun to take for granted, but again, itmeans that Angular will invoke the function not only when the view is first rendered, but anytime the associatedmodel is changed. In order to see this at work, we need to write a function that uses a model property.The add function below uses two model properties that are declared on the scope, operand1 and operand2. Angularwill invoke the function and render the result whenever either or both properties are changed.

    function AdditionController($scope) {

    $scope.operand1 = 0;

    $scope.operand2 = 0;

    $scope.add = function() {

    return $scope.operand1 + $scope.operand2;

    }

  • 13 | P a g e

    $scope.options = [0,1,2,3,4];

    }

    Since we've already covered several examples of the input directive in the previous chapter, let's instead useAngular's select directive to change the model values. You may have already noticed that the last line in the controllerprepares an options model, which we will use in a comprehensioninside this directive's ng-options parameter. The xfor x of our comprehension may seem redundant, since it just returns the original list of values, but the directiverequires us to write it nonetheless. (When your model is an array of objects, which is more typical, you might writea comprehension that picks out a name property for the option label, using x.name for x. Refer totheselect directive's parameters for more detail.)

    +

    = {{add()}}

    Ok, this works great. However, the design of the add function can be improved by generalization, which will comein handy if we ever want to use it with properties other than operand1 andoperand2. Break out your refactoringmanual and roll up your sleeves for some parameter extraction.

    function AdditionController($scope) {

    $scope.number = 2;

    $scope.add = function(operand1, operand2) {

    return operand1 + operand2;

    }

    }

    CallbacksThere is an example in the previous chapter demonstrating how an expression passed to ng-clickcan toggle aboolean model property. It initializes the model, authorized, within an ng-initdirective, then manipulates it using asimple, inline callback: ng-click="authorized = !authorized". Let's adapt the example by moving the modelinitialization and toggle logic to its proper home, a controller.

    function AuthController($scope) {

    $scope.authorized = true;

    $scope.toggle = function() {

    $scope.authorized = !$scope.authorized

  • 14 | P a g e

    };

    }

    Now that toggle is a function available on the scope, the argument to ng-click looks like a functioninvocation: toggle(). It isn't really an immediate invocation, of course. It's just a string that will be evaluated later,when the user clicks.

    The secret code is

    0123

    not for you to see

    ConclusionIn this chapter, we introduced JavaScript into our usage of Angular, in the form of controllers, which in an MVCpattern have the responsibility of preparing data for our views. Controllers make data available to views by declaringproperties on a scope object. In the next chapter, we'll take a closer look at scope objects, and learn how they areorganized as a hierarchy that roughly follows the structure of the DOM fragment managed by our application.

    ScopesWhat exactly is a scope in Angular? From the name, you might guess that it is a context for application state,possibly provided to protect us from using JavaScript's much-maligned global scope. That sounds like a simple,prudent thing for a framework to create, perhaps something we shouldn't even think about. Can we just move onto the next chapter?

    Not so fast. Although this will not be a long chapter, it does cover something very important: scope inheritanceand hierarchy. A typical Angular application might create a hierarchy of dozens, hundreds, or even thousands ofscopes.

    Before we get started, let's set up the environment for this chapter's examples.

  • 15 | P a g e

    SetupIn the Basics chapter, we learned how to add the ng-app directive to an element in order to tell Angular whichpart of your document it should process.

    The argument to ng-app is the name of our application's root module. (The example module name,app, is just aconvention.) Angular modules will be covered in depth in an upcoming chapter. For now, just consider this somebootstrapping boilerplate that you can ignore.angular.module('app', []);angular.module('app').config(['$controllerProvider', function($controllerProvider) {$controllerProvider.allowGlobals();

    }]);

    $scopeIn the last chapter, Controllers, we learned how to prepare the model by attaching properties toa$scope reference. Let's repeat the exercise.function NameController($scope) {$scope.name = "First";

    }Using the ng-controller directive, we can invoke the controller function above in the context of a DOM element.Any data that we assign to the scope provided to this controller will be available to us on and withinthis p element.

    {{name}}

  • 16 | P a g e

    CollectionsIn the preceding chapter, Scopes, we learned that Angular creates a new scope each time you invoke a controllerconstructor via ng-controller. There are other cases in which Angular creates new scopes, and perhaps the mostcommon is when working with collections of similar objects. Angular,unlike Backbone, does not have acomponent named Collection. However, its extensive support for working with collections of like objects merits achapter, as you will see.

    Set upIn addition to loading Angular from Google Hosted Libraries, the live examples in this page also loadthe Bootstrap styles for better-looking tables and lists.

    We then load our app module by passing its name to the ng-app directive. Our choice of the nameapp is aconvention, but not otherwise significant.

    We are ready to proceed with our interactive exploration of collections, iteration, and Angular.

    IterationIn regular JavaScript, when you iterate over a collection of similar objects in a for loop, you might declare a localvariable to reference the current element. For example:

    var items = [{name: "Item 1"},{name: "Item 2"}];for (var i = 0; i < items.length; i++) {var item = items[i];

    }document.body.innerHTML = item.name;Imagine that items is a collection of unknown length, and that we need to iterate over its members, displayingthe name property of each.

    ng-repeatJust as Angular creates a top-level Angular scope for expressions to protect us from creating variables onJavaScript's global scope, the built-in ng-repeat directive protects us from the situation shown in the first example,by creating an Angular scope for each iteration of the loop.

  • 17 | P a g e

    For each element in the comprehension passed to it, ng-repeat creates a new child scope with a property asspecified in the comprehension. In this case, the property name is item, but it could be anything. Edit theexample above, changing the usages of item to something different, like i or x.

    Object propertiesThe (key, value) in object syntax lets you loop over the properties of an object.

  • 18 | P a g e

    Generally speaking, the goal of modules is to achieve a separation of concerns by defining public APIs andlimiting the visibility of behavior (functions) and data (properties and variables). Most programming platformsinclude built-in support for modules, making their use something to take for granted. Client-side JavaScriptcurrently does not, creating a situation in which debates rage over the pros and cons of the popular add-onsolutions, such as CommonJS and Asynchronous module definition (AMD).

    Keep in mind when making comparisons to other solutions that Angular's module system is not a module loader.It does not load source code from files or the internet for you. What Angular provides is a built-in, proprietarymodule solution that works closely with its similarly built-in and proprietary dependency injection solution.Together, the two systems provide an impressive amount of general-purpose infrastructure. Although learning touse this functionality is within the ability of any developer, the question is, why do we need it?

    Modules and dependency injection are ordinarily an "all-in" proposition, but as we have seen, Angular allows usto get started without using its module system. So far, we have been able to accomplish quite a lot simply bydefining controllers as named functions on the global scope. This works because with a little configuration,the ng-controller directive searches for controller functions globally as well as in the module system. The less-complicated global approach to using Angular is permitted, but only up to a point.

    Why use Angular modules?In order to move beyond Angular's basic features, you will need to master its module system. This book does notseek to convince you of the intrinsic value of Angular's modules or dependency injection. When it comes to thegeneral problem of managing complexity in your JavaScript projects, you should arrive at your own best practices,and a simpler approach may be better. This book covers modules and dependency injection as necessary to useAngular.

    Therefore, let's survey the important features that require us to use the module system:

    Specialized components - To define your own controllers, directives, filters, and animations, you mustuse the module system. (Controllers may be excepted, as mentioned above.)

    Dependency injection - Although services are just ordinary JavaScript objects and functions, onlyservices created with the module system can be easily injected with their dependencies, as well asthemselves made available for dependency injection.

    External modules - There is an impressive ecosystem of free, open-source Angular add-ons, both fromthe core team and third parties. To use any of these libraries in your application, you must use Angular'smodule system.

    Load-time configuration - Angular's module system provides access to lifecycle hooks into Angular'sinternal configuration, as well as the configuration of add-on modules. The latter will be demonstrated atthe end of the final chapter when we configure a custom HTTP header.

    Testing - Angular's impressive testing infrastructure leverages its dependency injection system, which inturn depends on its module system.

    An upcoming chapter, Services, will demonstrate how to define providers for custom JavaScript components. Thischapter will show how to define a controller as well as to load external modules at the same time that it teachesyou the basics of the module system.

  • 19 | P a g e

    An Angular application can be initialized with only one root module. In our examples this module will benamed app by convention. This name isn't significant, but it is commonly seen in much of Angular'sdocumentation.angular.module('app', []);

    In the module.js example above, please take careful notice of the second argument to the modulemethod.Although it is just an empty, innocent-looking array ([]) in this usage, the presence of this second argument isextremely important. If you omit it, the behavior of angular.module changes radically. Talk about questionable APIdesign! When you call angular.module with the second argument, the function operates in create mode, andcreates a new module named app if no module with that name already exists. However, if youcall angular.module without the second argument, it operates in lookup mode. If a module with thegiven name already exists, it will return it; if not, it throws an error that helpfully mentions including the secondargument. We've got it right in this example, but just be aware of this important difference in your own code. Asfor the array argument, it is used to import External modules, which we will discuss presently, using Angular'sanimation module for our example.

    Loading the application moduleIn the HTML document that hosts our application, we can instruct Angular to load the application module bypassing its name to the ng-app directive.

    Any components that we add to our application module will be available for use. Let's see what it looks like todefine a controller within a module rather than on the global scope.

    Defining a controllerThe API for module includes functions for defining specialized Angular components. The only specializedcomponent that we are familiar with so far is the controller, so let's use the controllerfunction to create one. Firstwe need to obtain a reference to the application module. As explained above, we mustcall angular.module without its second argument, so that it operates in lookupmode.var app = angular.module('app');app.controller('MessageController', function($scope) {$scope.message = "This is a model.";

    });Now, somewhere within the element on which we invoked ng-app="app" , we can use ng-controllerto load ourcontroller.

    {{message}}

    As you can see, defining a controller within a module is a little more work than defining one on the global scope,but not too bad at all.

  • 20 | P a g e

    Chaining definitionsLet's say that we need to define two controllers for the template below.

    {{message}}

    {{message}}

    Loading modulesAnimations is a newer Angular feature that was added as a separately packaged module namedngAnimate. Thefirst step to using animations is to include the JavaScript file containing the module. The source code for themodule is part of the core Angular project, but it is distributed as a separate file, as shown below.

    It's time to really use the module function's second array parameter, to which we passed an empty array in theearlier example. This is where we can declare our module dependencies.angular.module('app', ['ngAnimate']);We have loaded ngAnimate into our application module. In our templates, the directives ng-show,ng-hide, ng-class, and several others will now check for both CSS and JavaScript animations that can be applied to DOMevents like add, enter, leave, move, and remove. Applying animations to supported DOM events is transparent inthe sense that no changes are required to our template code. If no animation code is present, either as CSS or asJavaScript registered via module.animation, our directive code will behave normally.

    Check the box to show the message

    The secret message.

  • 21 | P a g e

    Angular's built-in directives, such as ng-bind, ng-model, and input, have played a starring role in this book sincethe very first chapter, Basics. In fact, the Collections chapter focuses almost entirely on a single (quite powerful)directive, ng-repeat. It would seem that Angular's list of built-in directives would contain a solution for everysituation, but of course this isn't true. While Angular was conceived as a way to enable non-programmers to builddynamic web pages, it evolved into a platform that gives web developers the power to extend and customizeHTML. This means creating your own custom directives, which is exactly what we'll do in this chapter.In its simplest form, creating a custom directive is very similar to creating a custom filter, which is why welearned about filters first, in the preceding chapter. The outer function that we pass to thedirective function is adependency injection wrapper and factory function, also known in the Angular documentation as a recipe. It iscalled at most once, or never if the directive is not used, as we learned in the chapter on Services. Inside thisfactory function is another function, which will be called by Angular. This inner function is where we do theactual work of the directive. It is called thelink function.

    directiveThe appropriately-named directive function for registering custom directives is part of themodules API, so we needto begin by creating a root module for our application.

    angular.module('app', []);We load our root module by passing its name to ng-app.

    And with that, we're ready to create a directive. Let's start with a very simple directive named hello.angular.module('app').directive('hello', function() {return function(scope, element) {element.text("hello");

    };});