Angular Typescript RequireJS By Chris van Beek and Frank Folsche Luminis Arnhem
Jan 18, 2016
Angular Typescript RequireJS
By Chris van Beek and Frank FolscheLuminis Arnhem
About Chris
• Enthousiastic about technology! All kinds • Software Architect at Luminis Arnhem B.V.• Trainer at Luminis Arnhem B.V.• Specializes in Microsoft technology: .Net, Azure, Windows, Interactive Front-ends• Twitter: @cbeek• Blog: http://arnhem.luminis.eu/chris-van-beek• Email: [email protected]
About Frank
• Enthousiastic about technology! All kinds • Software Engineer at Luminis Arnhem B.V.• Specializes in Microsoft technology: .Net, Azure, Windows, Interactive Front-ends• Email: [email protected]
Introduction
• Lots of experience with Angular projects• Every project we learn about new tools and better ways• A lot of best practices are born from these experiences which I would like to share!
Contents
• AngularJS Basics• Typescript and Angular• RequireJS
AngularJSbasics
The environment, databinding and Model-View-Whatever
Why AngularJS?
JavaScript has issues‑ Global scope with many global functions‑ Few language constructs for structuring code‑ It was intended to be a scripting language‑ Weakly typed
7
Why AngularJS?
Other JavaScript libraries help, but aren’t suitable for large applications
‑ ‑ A fantastic tool for cross-browser compatible DOM interaction
and AJAX requests‑ No help for structuring or testing your code
‑ ‑ A great framework for data-binding‑ It’s only one small piece of everything you need when building
a large application. No help for testing your code
8
Why AngularJS?AngularJS to the rescue!
‑ Suitable for large applications in JavaScript‑ Based on MVC for structuring your application‑ Extends HTML‑ Cross-browser compatible‑ Testable from the ground up
9
Demo: Without Angular
AngularJS featuresAngularJS to the rescue!
‑ Two-way databinding through a declarative syntax‑ Model-View-Presenter architecture‑ Routing and deeplinking‑ Dependency injection‑ Everything is testable
11
Getting started
12
<!DOCTYPE html><html lang="nl">
<head><meta charset="utf-8" /><title>Hello Angular!</title><script src="angular.js"></script>
</head>
<body ng-app>
4 + 8 = {{4 + 8}}
</body></html>
Gives AngularJS the green light
AngularJS expression, result is 12
Instead of hosting this file yourself, you can also use a “Content Delivery Network”
• Data• State
• Glue
• Behavior & logic• Imperative• JavaScript +
AngularJS
• User interface• Declarative• HTML
Getting started: MVW architecture
AngularJS believes in seperation of concerns
13
View Scope Controller
• Data• State
• Glue
• Behavior & logic• Imperative• JavaScript +
AngularJS
• User interface• Declarative• HTML
Getting started: MVW architecture
14
View Scope Controller
var demoModule = angular.module('demoModule', []);demoModule.controller('demoController', function($scope) { $scope.name = 'world';});
<body ng-app="demoModule" ng-controller="demoController">
Hello {{name}}</body>
Getting started: Directives (1/4)
ng-repeat iterates over an array
15
Within an ng-repeat, you can also use special values• $index for the list index
of the item• $first, $middle and
$last
<ul><li ng-
repeat="car in cars">{{car.make}}
{{car.model}}</li>
</ul>
var demoModule = angular.module('demoModule', []);demoModule.controller('demoController', function($scope) { $scope.cars = [
{ make: 'Renault', model: 'Megane' },{ make: 'Audi', model: 'A4' },{ make: 'Toyota', model: 'Auris' }
];});
Getting started: Directives (2/4)
ng-click executes a function when clicking
16
Tells ng-click to execute the doSomething() function on our
$scopeThis looks like JavaScript, but it’s an Angular expression that closely resembles JavaScript
<input type="button" ng-lick="doSomething()" />
var demoModule = angular.module('demoModule', []);demoModule.controller('demoController', function($scope) { $scope.doSomething = function() {
console.log('Hello world!');};
});
Getting started: Directives (3/4)
ng-model offers two-way databinding
17
<input type="search" ng-model="filter" />Input: {{filter}}<input type="button" ng-click="doSomething()" />
var demoModule = angular.module('demoModule', []);demoModule.controller('demoController', function($scope) { $scope.doSomething = function() {
console.log('Filter: ' + $scope.filter);};
});
ng-model creates this property when typing in the input field
Getting started: Directives (4/4)
ng-show and ng-hide to show or hide an element
18
<input type="checkbox" ng-model="editmode"/><div ng-show="editmode">
<input type="text" ng-model="name"/></div><div ng-hide="editmode">
{{name}}</div>
ng-show/ng-hide use CSS’s display: none, thus screen readers and search engines will be unaffected
var demoModule = angular.module('demoModule', []);demoModule.controller('demoController', function($scope) {
$scope.name = 'Socrates';});
Demo time
• Calculator demo• Courses With Angular
19
Questions
20
?
Contents
• AngularJS• Typescript• RequireJS
What is TypeScript?
Alternative to Javascript because:• TypeScript is EcmaScript 6 (at lease for a big part).• TypeScript = Javascript.• TypeScript compiles to ES 3 or ES 5 Javascript.• ALL Existing libs work with TypeScript (Including Angular)• Runs on the browser but also in Node..(Compiles to Javascript)
Why?• Better tooling support because it has static typing (like Java and C#).• Has ECMA 6 Syntax .• Unlike Javascript, Typescript is object oriented.• Has language support for modules.• Object Oriented Javascript is hard!
Object Oriented JavaScript
Object Prototype• Objects can have a prototype, it can also be null sometimes.• Objects that share a prototype
• All inherit the same data• But they cannot directly alter them, setting a prop with the
name will hide the prototypes property• Adding properties to the prototype of a function, causes these
properties to inherit to objects created with this function as constructor, not to the function itself. Thus, setting the prototype, does not always causes inheritance.
• In other words, the prototype of the constructor function, becomes the prototype of the object.
• Javascript will look up in the prototype chain (prototype of prototype so on) until it finds a property.
JavaScript 25
Using prototypes
JavaScript 26
• When invoking a functions with the new operator, the this pointer inside a function will point to a newly created object
• Functions that make use of this are called Constructor functions and usually written capitalized
• The newly created object’s prototype will be set to the prototype of the constructor function
JavaScript 27
Constructor Functions
//Person revisited function Person(name, age) { this.name = name; this.age = age; this.sayHello = function () { console.log(this.name); }; } var person = new Person('Chris', 31); person.sayHello();
• Better to use prototype for methods. This way we can mimic object orientation and the function implementation does not get copied to every object.
• Method that use private vars (closures) or parameters from the constructor function should be defined on the object itself.
JavaScript 28
Constructor Functions and prototypes
//Person revisited function Person(name, age) { this.name = name; this.age = age; }Person.prototype.sayHello = function () { console.log(this.name); }; var person = new Person('Chris', 31); person.sayHello();
• Uses an immediately executed anonymous function to keep everything together
• Makes sure we don’t pollute the global scope
JavaScript 29
Problem: Object oriented Javascript
var Person = (function () { function Person(name, age) { this._name = name; this._age = age; } Person.prototype.sayHello = function () { }; return Person; })();
var person = new Person("chris", 31);
• Uses local vars and closures to create private variables
JavaScript 30
Create a proper classvar Person = (function () { function Person(name, age) { var _name = name; var _age = age; this.setName = function (name) { _name = name; }; this.getName = function () { return _name }; } Person.prototype.sayHello = function () { }; return Person; })();
Create an OO inheritancesub class
JavaScript 31
var Teacher=(function(){ function Teacher(name, age, courses) { Person.call(this, name, age); this.courses = courses; }
Teacher.prototype = Object.create(Person.prototype); Teacher.prototype.constructor = Employee;
Teacher.prototype.sayHello = function () { var result = Person.prototype.sayHello.call(this);
result += ‘ from a cool teacher’; return result; } return Teacher})();
Demo: Object Oriented Courses Revisited
Enter TypeScript
Types:
• String: string• Number: number• Boolean: boolean• “var”: any important!• Array: number[] of Array<number>• Enum: enum Color {Blue,Red,Green} : var c : Color = Color.Blue;• Any, bypasses type checking
Any
• Opts out type checking• You can also cast to any using <any> to opt out type checking
var notSure: any = 4; notSure = "maybe a string instead"; notSure = false; // okay, definitely a boolean
OO in Javascript
var Person = (function () { function Person(name, age) { this._name = name; this._age = age; } Person.prototype.sayHello = function () { }; return Person; })();
var person = new Person("chris", 31);
OO in TypeScript
• Has a structural type system. Does not compare types, but compares the structure of the different types
• If walks like a duck, sounds like a duck, it propably is..
Classes
• Very familiar if you are used to C# or Java• Allows us to build object oriented applications
class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } } var greeter = new Greeter("world");
Inheritance
class Animal { name: string; constructor(theName: string) { this.name = theName; } move(meters: number = 0) { alert(this.name + " moved " + meters + "m."); } }
class Snake extends Animal { constructor(name: string) { super(name); } move(meters = 5) { alert("Slithering..."); super.move(meters); } }
Interfaces
• Ducktyping! A type does not have to explicitly implement an interface to be compatible.
• Can contain almost everything• Optional properties with ?• Hybrid types• Function type• Static type vs instance type
Simple interfaces
• Performs ducktyping• Can have optional properties
interface LabelledValue { label: string; }
function printLabel(labelledObj: LabelledValue) { console.log(labelledObj.label); }
var myObj = { size: 10, label: "Size 10 Object" }; printLabel(myObj);
interface SquareConfig { color?: string; width?: number; }
Implementing interfaces
• Interfaces describe the public side of a class• Interfaces can also extend eachother, just like in Java and C#
interface SearchFunc { (source: string, subString: string): boolean; }
interface ClockInterface { currentTime: Date; setTime(d: Date); } class Clock implements ClockInterface { currentTime: Date; setTime(d: Date) { this.currentTime = d; }
Demo TypeScript Playground and Courses with TypeScript
• Types• Code completion• Generated Code
Modules
• Internal modules• External modules
Module pattern Javascriptvar eu;
(function(ns) {
var privateVar = 37;
function privateFunction() {};
ns.publicVar = 3.141592;
ns.publicFunction = function (){
};
}((eu = eu|| {}, eu.luminis = eu.luminis || {})));
Internal modules TypeScript
• Use reference path to order these files• Uses the Module keyword to create Modules.• You must tell the compiler if you want internal or external modules,
default is no module system, which means internal
Test.Greetr
Demo: Internal modules TypeScript
• Use Modules with the courses app• See the starting script tag hell• This does not solve the dependency hell
Questions
48
?
Contents
• AngularJS Basics• Typescript and Angular• RequireJS
External Modules
• Support for CommonJS (for Node.js) en AMD/Require (for web apps).
• Module keyword not needed. Every file is a module• “import someModule=require(‘path’)” to specify dependencies.• AMD needs an AMD compliant loader like require.js.• You need to bootstrap this yourself• Use this when you want dependency management or lazy loading
(RequireJS)
Module Loaders
• Javascript has no module system• Script tags in your browser in the right order are a lot of hassle• RequireJS or Browserify• Typescript supports RequireJS!
RequireJS
• Requires a specific structure in your javascript files• Can also handle libraries that know nothing about Require (like Angular)• Offers fysical modules (files) instead of logical modules that Angular offers
RequireJS Demo
• RequireJS and Typescript• Typescript code• Look at the compiled typescript code• Look at the combination of typescript and Angular, Controller and Service
Front-end build
• We are used to MSBuild or Jenkins• Front-end build tools support more and typical web build tasks• Typescript compile• SSAS compile• Uglyify and concat• Angular tweaks (like TemplateCache!)• All runs on NodeJS plugins
Front-end build
Gulp‑ Faster(in mem streams vs copy and open/closing files)‑ Code instead of config‑ Is about streams that get sent from one task to another. Mix and match tasks that work on
streams
Grunt‑ Config over code‑ A lot of tasks executed in a certain order‑ Copies a lot of files
RequireJS Demo
• Sample from real world project (anonymised)• Look at the Html without require
• Demo with Require• Config for RequireJS
Demo gulp
• Look at gulp file and look at best practices• Typescript compile• RequireJs Concat• Mangling• Angular template caching
Using existing frameworks
• Every Javascript framework is a typescript framework• Usable because of the any type and the declare keyword• To really benefit of typescript, use .d files• Zie: https://github.com/borisyankov/DefinitelyTyped
Questions
59
?