Hello, my name is




Angular JS


Before we start


We need:




  • Knowledge of JavaScript (HTML & CSS)
  • Understanding of JSON and APIs

We DON'T need:

  • Assembly
  • Bash
  • COBOL
  • C
  • C++
  • Coldfusion
  • Java
  • MySQL
  • PHP
  • Ruby
  • Shell
  • Et Cetera
  • Et Cetera

Why AngularJs


  • Relatively low learning curve *
  • POJOs throughout
  • Built on solid, modular opinions
  • Created and used by Google
    • YouTube (PS3)
    • DoubleClick
  • Community 
    • #angular on freenode
    • StackOverflow
    • egghead.io

ChevronJs?




<     ==      'angle bracket'         AngularJs

But what about...


  • Knockout.js
  • Ember.js
  • Backbone.js
  • YUI3
  • Dojo
  • ExtJs
  • jQuery
  • MooTools
  • Prototype
  • PhoneJs
  • ? ? ?

Where can I find it?



http://angularjs.org


https://docs.angularjs.org/api


http://plnkr.co

While there is IE 8




Stay within 1.2.x



And follow the notes on:                                                 

What is AngularJs?


MVC

MVVM

MV?




No, really, what is it?


SDC


S - Service - Similar to a Model

D - Directive - Similar to a View *

C - Controller - Similar to a Controller? 

*

AngularJs uses HTML as your template language through the use of directives and custom (data-) attributes. 


This is smart, quick, and useful.



õ


Let's give it a shot

Getting it on the page


Include it in the <head>

<!doctype html>
<html>
  <head>
    ...
    <script src="//cdn.manheim.com/assets/js/angular.js"></script>
  </head>
  ...
</html>

Add a little Magic


Add `ng-app` upstream

<!doctype html>
<html>
  <head>
    ...
    <script src="//cdn.manheim.com/assets/js/angular.js"></script>
  </head>
  <body ng-app>
      {{1 + 2}}
  </body>
</html>

... anywhere upstream

What's actually going on


`ng-app` sought out by `angular.bootstrap`

this "magic"
 <body ng-app="clarityApp">...</body>

is actually doing this
angular.element(document).ready(function () {
    angular.bootstrap(document, ['clarityApp']);
});

not so magical, right?

But what about validation??



Use `data-` prefixes if you want.


<body ng-app>...</body> 


 <body data-ng-app>...</body>


But I don't want logic in my layout!


õ.Ô

Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.
~ W3C Specification



Creating an app

<!doctype html>
<html>
  <head>
    <title>Clarity App</title>
    <script src="/js/angular.js"></script>
  </head>
  <body>
    <div ng-app="clarityApp">      <!-- contents go here -->
    </div>
    <script src="/js/clairtyApp.js"></script>
  </body>
</html>
// js/clarityApp.js
;(function () {

  'use strict';  
  var app = angular.module('clarityApp', []);

}());

Controllers


define our module's behavior by
defining functions and values

$scope

First controller


app.controller('SearchCtrl', function () {

  var _this = this;

  this.count = 0;

  this.btnPress = function () {
    _this.count++;
  };

});

<div ng-controller="SearchCtrl as search">
  {{search.count}}<br>
  <button ng-click="search.btnPress()">++</button>
</div>

Don't take my word for it


Dependency Injection of $scope


app.controller('SearchCtrl', function ($scope) {
  // ... 
});

Doesn't work when minimized

app.controller('SearchCtrl', ['$scope', function ($scope) {
  // ... 
}]);

$scope API

$watch
$scope.$watch(function () {
    return _this.count;
}, function (newVal, prevVal) {
    if (newVal === prevVal) { return; } // happens during initialization
    // do stuff with the newVal
});

$apply
$scope.$apply(); // runs $digest

$on; $emit; $broadcast
$scope.$on('someEvent', function () { });
$scope.$emit('someEvent'); // crawls scope tree firing the event
$scope.$broadcast('someEvent'); // tells everyone regardless of tree

And more!


Services


Able to keep data logic out of the scope of the controller




Can be shared between controllers

Let's build one!


app.service('TwitterService', function () {
  var _this = this;
  this.results = [];

  this.search = function (query) {
  };
});

app.controller('SearchCtrl', function (TwitterService) {
  var _this = this;

  this.query = '';

  this.btnSearch = function () {
    TwitterService.search(_this.query);
  };
});

DI in a Service

app.service('TwitterService', function ($http) {
  var _this = this;
  this.results = [];

  this.search = function (query) {
    return $http({
      url: 'https://api.twitter.com/1.1/search/tweets.json',
      params: { q: query }
    }).then(function (resp) {
      _this.results = resp.statuses; // array of statuses
      return resp.statuses; 
    });
  };
});
app.controller('ResultsCtrl', function ($scope, TwitterService) {
  var _this = this;
  this.results = [];

  $scope.$watch(function () {
    return TwitterService. results;
  }, function (newVal, prevVal) {
    if (newVal === prevVal) { return; }
    _this.results = newVal;
  });
});

Don't take my word for it


Directives


marker on an HTML tag that tells Angular to
run or reference some JS code


 <body ng-app></body>
 <body ng-app="clarityApp"></body>
 <body data-ng-app></body>
 <body data-ng-app="clarityApp"></body>

AECM?


A: Attribute

E: Element

C: Class

M: coMment

Real life example

<div ng-controller="ResultsCtrl as results">
  <ul>
    <li class="media" ng-repeat="status in results.results">
      <div class="img">
        <img src="{{status.user.profile_image_url}}" width="60" height="60">
      </div>
      <div class="content">
        <h2>{{status.user.name}} {{"@" + status.user.screen_name}}</h2>
        <p>{{status.text}}</p>
      </div>
    </li>
  </ul>
</div>

There so much more!


Custom directives

 <mui-ymmt mui-year="2014" mui-make="Tesla" mui-model="Model S"/>

Transclusion

<mui-media mui-image="//placekitten.com/60/60">
  <h2>Marvin the Cat</h2>
  <p>This is a very special kitty!</p>
</mui-media>

Out of scope of this talk :-(

Filters

add filters using pipes

Currency
 {{ 3.2 | currency }} // $3.20

Date
 {{ '1388123412323' | date }} // Dec 27, 2013

Strings
 {{ 'Hello, world!' | uppercase }} // HELLO, WORLD!
 {{ 'Hello, world!' | lowercase }} // hello, world!

but wait, there's more


Combining them

 {{ '1388123412323' | date | uppercase }} // DEC 27, 2013



This is just the beginning!

Custom Filters

app.filter('userLink', function () {    
  return function (str) {
    if (typeof str !== 'string') {
      str = String(str);
    }
      
    return str.replace(/@([a-zA-Z0-9_]+)/gi, 
       '<a href="http://twitter.com/$1" target="_blank" class="tAt">@$1</a>'
    );
  };
});

Gotchas!



Too good to be true?

Minimization + DI


app.controller('SearchCtrl', ['$scope', function ($scope) {
  // ... 
}]);

"AJAX" and SEO


Search engines don't run javascript

<!doctype html>
<html>
  <head>
    <script src="/js/angular.js"></script>
  </head>
  <body>
    <script src="/js/app.js"></script>
  </body>
</html>

Alas, my love,

you do me wrong...



IE8 1.2.x - none of the newness

Another time

  • Angular specific CSS
  • Templates
  • Custom directives
  • $scope inheritance
  • Factory > Provider > Service
  • ng-route
  • angular-ui
  • modules and organization

Thanks!


Me: Anthony Pipkin

http://a.pipk.in
@apipkin
github.com/apipkin
linkedin.com/in/apipkin



Questions? 

Introduction To Angular JS

By Anthony Pipkin

Introduction To Angular JS

  • 1,755