├── .gitignore ├── 01-getting-started-with-angular2 ├── favicon.ico ├── images │ ├── batman.jpg │ ├── dashboard-section-1.png │ ├── dashboard-section-2.png │ ├── dashboard-section-3.png │ ├── flash.svg │ └── superman.png ├── index.html ├── lessons-server.ts ├── package.json ├── src │ ├── 01-mvc-hello-world │ │ ├── hello_world.ts │ │ ├── index.html │ │ └── tsconfig.json │ ├── 02-template-syntax-properties │ │ ├── app.ts │ │ ├── index.html │ │ ├── lesson-2.css │ │ └── tsconfig.json │ ├── 03-template-syntax-interpolation │ │ ├── app.ts │ │ ├── index.html │ │ ├── lesson.css │ │ └── tsconfig.json │ ├── 04-template-syntax-events │ │ ├── app.ts │ │ ├── index.html │ │ ├── lesson-4.css │ │ └── tsconfig.json │ ├── 05-template-syntax-components-essentials │ │ ├── app.ts │ │ ├── color_picker.ts │ │ ├── color_previewer.ts │ │ ├── constants.ts │ │ ├── index.html │ │ ├── lesson.css │ │ └── tsconfig.json │ ├── common-styles │ │ ├── common.css │ │ └── tsconfig.json │ ├── components-inputs-and-outputs │ │ ├── app.ts │ │ ├── index.html │ │ ├── search-box │ │ │ ├── search-box.component.css │ │ │ ├── search-box.component.html │ │ │ └── search-box.component.ts │ │ └── tsconfig.json │ ├── core-directives-ng-for │ │ ├── app.ts │ │ ├── hero.ts │ │ ├── heroes.ts │ │ ├── index.html │ │ ├── lesson.css │ │ └── tsconfig.json │ ├── core-directives-ngif │ │ ├── app.ts │ │ ├── index.html │ │ ├── lesson.css │ │ └── tsconfig.json │ ├── core-directives-ngstyle-ngclass │ │ ├── app.ts │ │ ├── hero.ts │ │ ├── heroes.ts │ │ ├── index.html │ │ ├── lesson.css │ │ └── tsconfig.json │ ├── directives-intro │ │ ├── app.ts │ │ ├── collapse-on-click.directive.ts │ │ ├── directives-intro.css │ │ ├── index.html │ │ └── tsconfig.json │ ├── directives │ │ ├── app.ts │ │ ├── index.html │ │ ├── lesson.css │ │ ├── show-one-container.ts │ │ ├── show-one-trigger.ts │ │ ├── show-one.ts │ │ └── tsconfig.json │ ├── exercise-color-sample │ │ ├── app.ts │ │ ├── color-sample.ts │ │ ├── index.html │ │ └── tsconfig.json │ ├── forms-model-driven │ │ ├── app.ts │ │ ├── checkIfTitleExists.ts │ │ ├── index.html │ │ ├── lesson.ts │ │ ├── number-field.component.ts │ │ ├── tsconfig.json │ │ └── validateDuration.ts │ ├── forms-signup-exercise │ │ ├── app.ts │ │ ├── confirmPassword.ts │ │ ├── index.html │ │ └── tsconfig.json │ ├── forms-template-driven │ │ ├── app.ts │ │ ├── index.html │ │ ├── lesson.ts │ │ ├── tsconfig.json │ │ ├── validate-duration.directive.ts │ │ └── validateDuration.ts │ ├── introduction-to-pipes │ │ ├── app.ts │ │ ├── index.html │ │ ├── lesson.css │ │ ├── sort.pipe.ts │ │ └── tsconfig.json │ ├── modules-intro │ │ ├── app.ts │ │ ├── index.html │ │ ├── lessons-list.component.js │ │ ├── lessons-list.component.js.map │ │ ├── lessons-list.component.ts │ │ ├── lessons.js │ │ ├── lessons.js.map │ │ ├── lessons.module.ts │ │ ├── lessons.service.js │ │ ├── lessons.service.js.map │ │ ├── lessons.service.ts │ │ ├── lessons.ts │ │ ├── tsconfig.json │ │ ├── xhr-headers.js │ │ ├── xhr-headers.js.map │ │ └── xhr-headers.ts │ ├── router-exercise │ │ ├── app.ts │ │ ├── dashboard-header.ts │ │ ├── impresssions-by-country.component.ts │ │ ├── index.html │ │ ├── page-views-by-browser.component.ts │ │ ├── page-views-pie-chart.component.ts │ │ ├── router-config.ts │ │ └── tsconfig.json │ ├── router-introduction │ │ ├── all-lessons.component.ts │ │ ├── app.ts │ │ ├── chat.ts │ │ ├── course-detail-activate.guard.ts │ │ ├── course-detail-deactivate.guard.ts │ │ ├── course-detail.component.ts │ │ ├── courses-list.component.ts │ │ ├── courses-router-config.ts │ │ ├── courses.component.ts │ │ ├── courses.module.ts │ │ ├── coursesData.ts │ │ ├── home.component.ts │ │ ├── index.html │ │ ├── lesson.ts │ │ ├── lessons-list.component.ts │ │ ├── lessonsData.ts │ │ ├── playlist.component.ts │ │ ├── router-config.ts │ │ ├── router.css │ │ ├── shared.module.ts │ │ └── tsconfig.json │ ├── services-http │ │ ├── app.ts │ │ ├── index.html │ │ ├── init-observable.ts │ │ ├── lesson.ts │ │ ├── lessons-list.component.ts │ │ ├── lessons.service.ts │ │ ├── tsconfig.json │ │ └── xhr-headers.ts │ ├── services-intro │ │ ├── app.ts │ │ ├── index.html │ │ ├── lessons-list.component.ts │ │ ├── lessons.service.ts │ │ ├── lessons.ts │ │ ├── tsconfig.json │ │ └── xhr-headers.ts │ └── typescript-introduction │ │ ├── tsconfig.json │ │ └── typescript-introduction.ts ├── system.config.js └── yarn.lock ├── README.md └── theme ├── package.json └── styles ├── angular-academy-lessons-theme.scss ├── project ├── _card.scss ├── _centering.scss ├── _colors.scss ├── _defaults.scss ├── _fonts.scss ├── _getting_started_lessons.scss ├── _input.scss ├── _layout.scss └── _tabs.scss └── vendors └── _normalize.scss /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | typings 3 | tsd_typings/ 4 | npm-debug.log 5 | dist/ 6 | .idea 7 | .DS_Store 8 | tmp 9 | *.js 10 | *.map -------------------------------------------------------------------------------- /01-getting-started-with-angular2/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular-university/courses/ea4ee16fbb5e7d97beb1a9aa3fadd05928e90881/01-getting-started-with-angular2/favicon.ico -------------------------------------------------------------------------------- /01-getting-started-with-angular2/images/batman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular-university/courses/ea4ee16fbb5e7d97beb1a9aa3fadd05928e90881/01-getting-started-with-angular2/images/batman.jpg -------------------------------------------------------------------------------- /01-getting-started-with-angular2/images/dashboard-section-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular-university/courses/ea4ee16fbb5e7d97beb1a9aa3fadd05928e90881/01-getting-started-with-angular2/images/dashboard-section-1.png -------------------------------------------------------------------------------- /01-getting-started-with-angular2/images/dashboard-section-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular-university/courses/ea4ee16fbb5e7d97beb1a9aa3fadd05928e90881/01-getting-started-with-angular2/images/dashboard-section-2.png -------------------------------------------------------------------------------- /01-getting-started-with-angular2/images/dashboard-section-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular-university/courses/ea4ee16fbb5e7d97beb1a9aa3fadd05928e90881/01-getting-started-with-angular2/images/dashboard-section-3.png -------------------------------------------------------------------------------- /01-getting-started-with-angular2/images/flash.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 17 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/images/superman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular-university/courses/ea4ee16fbb5e7d97beb1a9aa3fadd05928e90881/01-getting-started-with-angular2/images/superman.png -------------------------------------------------------------------------------- /01-getting-started-with-angular2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 |
21 | 22 | 23 |
Getting Started with Angular - The Fundamentals
24 |
Lessons
25 | 26 |
27 | 50 |
51 | 52 |
53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/lessons-server.ts: -------------------------------------------------------------------------------- 1 | declare const require; 2 | 3 | 4 | var express = require('express'); 5 | var bodyParser = require('body-parser'); 6 | var _ = require('lodash'); 7 | import {lessonsData} from "./src/services-intro/lessons"; 8 | 9 | 10 | var app = express(); 11 | 12 | app.use(express.static('.')); 13 | app.use(bodyParser.json()); 14 | app.use(bodyParser.text()); 15 | 16 | 17 | const lessons = lessonsData; 18 | 19 | 20 | app.route('/lessons') 21 | .get((req, res) => { 22 | 23 | var filtered = lessons; 24 | 25 | if (req.query.search) { 26 | console.log(req.query.search); 27 | filtered = filtered.filter( 28 | lesson => lesson.description.indexOf(req.query.search) != - 1); 29 | } 30 | 31 | res.status(200).json(filtered); 32 | }) 33 | .post((req, res) => { 34 | lessons.push(req.body); 35 | res.status(200).send(); 36 | }); 37 | 38 | app.route('/lessons/:lessonId') 39 | .delete((req,res) => { 40 | const lessonId = req.params.lessonId; 41 | console.log("deleting lesson ", lessonId); 42 | const index = _.find(lessons, 43 | lesson => lesson.id === lessonId 44 | ); 45 | lessons.splice(index, 1); 46 | res.status(200).send(); 47 | }); 48 | 49 | 50 | app.route('/flakylessons') 51 | .get((req, res) => { 52 | 53 | const num = Math.round(Math.random() * 10); 54 | 55 | if (num % 2 == 0) { 56 | res.status(200).json(lessons); 57 | } 58 | else { 59 | res.status(500).send(); 60 | } 61 | 62 | }); 63 | 64 | 65 | 66 | 67 | app.route('/delayedlessons') 68 | .get((req, res) => { 69 | 70 | setTimeout(() => { 71 | 72 | var filtered = lessons; 73 | 74 | if (req.query.search) { 75 | console.log(req.query.search); 76 | filtered = filtered.filter( 77 | lesson => lesson.description.indexOf(req.query.search) != - 1); 78 | } 79 | 80 | res.status(200).json(filtered); 81 | 82 | }, 1000); 83 | 84 | }); 85 | 86 | 87 | function redirectRouterLessonUnmatched(req,res) { 88 | res.sendFile("index.html", { root: './src/router-introduction' }); 89 | } 90 | 91 | app.use(redirectRouterLessonUnmatched); 92 | 93 | 94 | var server = app.listen(8080, function() { 95 | console.log("Server running at http://localhost:" + server.address().port); 96 | }); 97 | 98 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-for-beginnners", 3 | "description": "Angular For Beginners - Course Lessons", 4 | "version": "1.0.0", 5 | "scripts": { 6 | "start": "./node_modules/.bin/ts-node lessons-server.ts" 7 | }, 8 | "devDependencies": { 9 | "http-server": "^0.9.0" 10 | }, 11 | "dependencies": { 12 | "@angular/animations": "^5.0.0", 13 | "@angular/common": "^5.0.0", 14 | "@angular/compiler": "^5.0.0", 15 | "@angular/core": "^5.0.0", 16 | "@angular/forms": "^5.0.0", 17 | "@angular/http": "^5.0.0", 18 | "@angular/platform-browser": "^5.0.0", 19 | "@angular/platform-browser-dynamic": "^5.0.0", 20 | "@angular/router": "^5.0.0", 21 | "core-js": "^2.4.1", 22 | "rxjs": "^5.5.2", 23 | "zone.js": "^0.8.14", 24 | "body-parser": "1.15.1", 25 | "express": "4.13.4", 26 | "lodash": "4.13.1", 27 | "systemjs": "0.19.27", 28 | "ts-node": "3.0.2", 29 | "typescript": "2.2.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/01-mvc-hello-world/hello_world.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | 8 | @Component({ 9 | selector:'hello-world', 10 | template: `

Hello World !

` 11 | }) 12 | export class HelloWorld { 13 | 14 | 15 | } 16 | 17 | 18 | @NgModule({ 19 | declarations: [HelloWorld], 20 | imports: [BrowserModule], 21 | bootstrap: [HelloWorld] 22 | }) 23 | export class AppModule { 24 | 25 | } 26 | 27 | platformBrowserDynamic().bootstrapModule(AppModule); 28 | 29 | 30 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/01-mvc-hello-world/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Really Understanding Angular - The Fundamentals
48 |
MVC Hello World Component - Controllers and Templates
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/01-mvc-hello-world/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/02-template-syntax-properties/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | 8 | 9 | @Component({ 10 | selector: 'app', 11 | template: ` 12 | 13 |
14 | Color Sample
15 | 16 | 17 | 18 | 19 | 20 | ` 21 | }) 22 | export class App { 23 | 24 | 25 | } 26 | 27 | 28 | 29 | 30 | @NgModule({ 31 | declarations: [App], 32 | imports: [BrowserModule], 33 | bootstrap: [App] 34 | }) 35 | export class AppModule { 36 | 37 | } 38 | 39 | platformBrowserDynamic().bootstrapModule(AppModule); 40 | 41 | 42 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/02-template-syntax-properties/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Really Understanding Angular - The Fundamentals
48 |
Template Syntax - Properties
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/02-template-syntax-properties/lesson-2.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .lesson-2 { 5 | padding-left: 100px; 6 | } 7 | 8 | .color-sample { 9 | background: darkred; 10 | color: white; 11 | padding: 5px 10px; 12 | border:1px solid gray; 13 | border-radius: 4px; 14 | width: 175px; 15 | } 16 | 17 | button[disabled] { 18 | cursor: not-allowed; 19 | } 20 | 21 | input, button, .color-sample { 22 | box-sizing: border-box; 23 | margin-bottom: 15px; 24 | } 25 | 26 | input, button { 27 | display: block; 28 | } 29 | 30 | 31 | input[required] { 32 | border-color: red; 33 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/02-template-syntax-properties/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/03-template-syntax-interpolation/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | 8 | 9 | @Component({ 10 | selector: 'app', 11 | template: ` 12 | 13 | {{ model?.message }} 14 | 15 | ` 16 | }) 17 | export class App { 18 | 19 | message = 'Hello World !'; 20 | 21 | condition = true; 22 | 23 | model = { 24 | message: 'Hello World !' 25 | }; 26 | 27 | get calculatedValue() { 28 | return "Calculated Value"; 29 | } 30 | 31 | } 32 | 33 | 34 | 35 | @NgModule({ 36 | declarations: [App], 37 | imports: [BrowserModule], 38 | bootstrap: [App] 39 | }) 40 | export class AppModule { 41 | 42 | } 43 | 44 | platformBrowserDynamic().bootstrapModule(AppModule); 45 | 46 | 47 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/03-template-syntax-interpolation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Getting Started with Angular 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Getting Started with Angular - The Fundamentals
48 |
Template Syntax - Interpolation
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/03-template-syntax-interpolation/lesson.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | label { 4 | margin-right: 15px; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/03-template-syntax-interpolation/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/04-template-syntax-events/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | 8 | 9 | @Component({ 10 | selector: 'app', 11 | template: ` 12 | 13 | {{input.value}} 14 | 15 | 16 | 17 | ` 18 | }) 19 | export class App { 20 | 21 | onClick() { 22 | alert("Hello !"); 23 | 24 | debugger; 25 | } 26 | 27 | 28 | } 29 | 30 | 31 | 32 | @NgModule({ 33 | declarations: [App], 34 | imports: [BrowserModule], 35 | bootstrap: [App] 36 | }) 37 | export class AppModule { 38 | 39 | } 40 | 41 | platformBrowserDynamic().bootstrapModule(AppModule); 42 | 43 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/04-template-syntax-events/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Really Understanding Angular - The Fundamentals
48 |
Template Syntax - Events and Introduction to Zones
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/04-template-syntax-events/lesson-4.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | .lesson-4 { 4 | padding-left: 70px; 5 | } 6 | 7 | .toogle-panel { 8 | background: cornflowerblue; 9 | color: white; 10 | padding: 5px 10px; 11 | border:1px solid gray; 12 | border-radius: 4px; 13 | width: 100px; 14 | height: 50px; 15 | margin-bottom: 20px; 16 | margin-top: 20px; 17 | } 18 | 19 | input { 20 | margin-bottom: 20px; 21 | margin-right: 10px; 22 | } 23 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/04-template-syntax-events/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/05-template-syntax-components-essentials/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {ColorPicker} from "./color_picker"; 8 | import {ColorPreviewer} from "./color_previewer"; 9 | 10 | 11 | @Component({ 12 | selector: 'app', 13 | template: ` 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ` 23 | }) 24 | export class App { 25 | 26 | color:string; 27 | 28 | 29 | } 30 | 31 | 32 | 33 | @NgModule({ 34 | declarations: [App, ColorPreviewer, ColorPicker], 35 | imports: [BrowserModule], 36 | bootstrap: [App] 37 | }) 38 | export class AppModule { 39 | 40 | } 41 | 42 | platformBrowserDynamic().bootstrapModule(AppModule); 43 | 44 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/05-template-syntax-components-essentials/color_picker.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component, Output, EventEmitter, Input} from "@angular/core"; 4 | import {BLUE, RED} from "./constants"; 5 | 6 | 7 | @Component({ 8 | selector: 'color-picker', 9 | template: ` 10 | 11 |
Pick a Color:
12 | 13 |
14 |
15 |
16 |
17 | 18 | ` 19 | }) 20 | export class ColorPicker { 21 | 22 | @Input() 23 | color:string; 24 | 25 | @Output("color") 26 | colorOutput = new EventEmitter(); 27 | 28 | choose(color) { 29 | this.colorOutput.emit(color); 30 | } 31 | 32 | reset() { 33 | this.colorOutput.emit('black'); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/05-template-syntax-components-essentials/color_previewer.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, Input} from "@angular/core"; 3 | 4 | @Component({ 5 | selector: 'color-previewer', 6 | template: ` 7 |
8 | Preview Text Color 9 |
10 | ` 11 | }) 12 | export class ColorPreviewer { 13 | 14 | @Input() 15 | color:string; 16 | 17 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/05-template-syntax-components-essentials/constants.ts: -------------------------------------------------------------------------------- 1 | 2 | export const BLUE = '#b13138'; 3 | 4 | export const RED = '#1976d2'; 5 | 6 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/05-template-syntax-components-essentials/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 36 | 37 | 38 | 39 | 40 | 41 | 44 | 45 |
46 | 47 | 48 |
Getting Started with Angular - The Fundamentals
49 |
Components Essentials
50 | 51 |
52 | 53 |
54 | 55 |
56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/05-template-syntax-components-essentials/lesson.css: -------------------------------------------------------------------------------- 1 | 2 | .lesson { 3 | text-align: center; 4 | max-width: 330px; 5 | } 6 | 7 | .color-picker { 8 | 9 | 10 | } 11 | 12 | .color-title { 13 | text-decoration: underline; 14 | font-weight: bold; 15 | margin-bottom: 10px; 16 | } 17 | 18 | .color-sample { 19 | height: 50px; 20 | width:50px; 21 | border: 1px solid gray; 22 | display: inline-block; 23 | border-radius: 4px; 24 | margin-right: 10px; 25 | cursor: pointer; 26 | } 27 | 28 | 29 | .color-sample-red { 30 | background: #1976d2; 31 | 32 | } 33 | 34 | 35 | .color-sample-blue { 36 | background: #b13138; 37 | } 38 | 39 | 40 | 41 | .color-previewer { 42 | margin-top: 50px; 43 | margin-bottom: 50px; 44 | font-weight: bold; 45 | font-size: 21px; 46 | text-transform: uppercase; 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/05-template-syntax-components-essentials/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/common-styles/common.css: -------------------------------------------------------------------------------- 1 | 2 | .lesson { 3 | margin: 25px auto 0 auto; 4 | max-width: 350px; 5 | } 6 | 7 | .lessons-list { 8 | padding: 10px 10px 0 10px; 9 | display: table-cell; 10 | margin-bottom: 15px; 11 | } 12 | 13 | .lessons-list tr { 14 | border-bottom: 1px solid darkgray; 15 | cursor: pointer; 16 | } 17 | 18 | .lessons-list td { 19 | padding-bottom: 5px; 20 | } 21 | 22 | .lesson-logo { 23 | height: 20px; 24 | margin-right: 10px; 25 | } 26 | 27 | .add-lesson { 28 | width: 350px; 29 | margin-bottom: 15px; 30 | } 31 | 32 | .md-icon { 33 | font-family: 'Material Icons'; 34 | text-rendering: optimizeLegibility; 35 | font-feature-settings: "liga" 1; 36 | font-style: normal; 37 | text-transform: none; 38 | line-height: 1; 39 | width: 24px; 40 | height: 24px; 41 | display: inline-block; 42 | overflow: hidden; 43 | -webkit-font-smoothing: antialiased; 44 | -moz-osx-font-smoothing: grayscale; 45 | } 46 | 47 | .collapsible-indicator { 48 | font-size: 30px; 49 | line-height:30px; 50 | } 51 | 52 | 53 | .collapsible-section { 54 | padding: 0 20px 20px 20px; 55 | } 56 | 57 | .collapsed .collapsible-section { 58 | display: none; 59 | } 60 | 61 | 62 | .disable-text-selection { 63 | -webkit-touch-callout: none; 64 | -webkit-user-select: none; 65 | -moz-user-select: none; 66 | -ms-user-select: none; 67 | user-select: none; 68 | } 69 | 70 | 71 | .course-logo { 72 | height: 75px; 73 | margin: 0 auto; 74 | background-color: #FAFAFA; 75 | background-image: url(https://angular-academy.s3.amazonaws.com/main-logo/main-page-logo-small-hat.png); 76 | background-repeat: no-repeat; 77 | background-position-x: center; 78 | background-size: 65px; 79 | background-position-y: center; 80 | } 81 | 82 | form label { 83 | width: 100px; 84 | display: inline-block; 85 | text-align: right; 86 | vertical-align: top; 87 | margin-right: 5px; 88 | } 89 | 90 | .field-error-message { 91 | text-align: right; 92 | padding-right: 68px; 93 | font-size: 16px; 94 | color: #a10000; 95 | } 96 | 97 | form fieldset { 98 | margin-bottom: 20px; 99 | } 100 | 101 | form textarea { 102 | width: 170px; 103 | } 104 | 105 | form input[type='radio'] { 106 | box-shadow: none; 107 | width: 20px; 108 | vertical-align: bottom; 109 | margin-left: 10px; 110 | } 111 | 112 | form button[type='submit'] { 113 | float: right; 114 | margin-right: 75px; 115 | } 116 | 117 | .debug { 118 | clear: both; 119 | font-size: 14px; 120 | } 121 | 122 | .debug h3 { 123 | margin-top: 20px; 124 | margin-bottom: 5px; 125 | } 126 | 127 | .form-field { 128 | margin-bottom: 15px; 129 | } 130 | 131 | .lesson-button { 132 | background: #1976d2; 133 | color: white; 134 | font-weight: bold; 135 | } 136 | 137 | .lesson-button[disabled] { 138 | background: grey; 139 | color: white; 140 | cursor: not-allowed; 141 | } 142 | 143 | .top-menu { 144 | margin-bottom: 30px; 145 | } 146 | 147 | 148 | 149 | 150 | .ng-dirty.ng-invalid { 151 | border: 2px solid #ff2118; 152 | } 153 | 154 | form.ng-dirty.ng-invalid { 155 | border:none; 156 | } 157 | 158 | 159 | .l-header img { 160 | cursor: pointer; 161 | } 162 | 163 | .youtube-logo { 164 | max-height: 100px; 165 | border-radius: 4px; 166 | } 167 | 168 | .lessons-list { 169 | text-align: left; 170 | } 171 | 172 | .home-screen { 173 | margin-top: 50px; 174 | } 175 | 176 | .courses-list { 177 | padding: 5px 10px; 178 | text-align: left; 179 | } 180 | 181 | 182 | table.courses-list tr { 183 | border-bottom: 1px solid darkgray; 184 | } 185 | 186 | table.courses-list tr td { 187 | padding: 5px 0; 188 | } 189 | 190 | table.courses-list tr td.description { 191 | padding-right: 15px; 192 | } 193 | 194 | table.courses-list tr td:first-child { 195 | padding-left: 15px; 196 | } 197 | 198 | table.courses-list tr td:last-child { 199 | padding-right: 15px; 200 | } 201 | 202 | ul.top-menu > li > a.menu-active { 203 | color: #ee1c1b; 204 | font-weight: bold; 205 | text-decoration: underline; 206 | } 207 | 208 | .nav-button { 209 | margin-bottom: 20px; 210 | } 211 | 212 | .playlist { 213 | float: right; 214 | } 215 | 216 | .main-container .list { 217 | display: inline-block; 218 | max-width: 270px; 219 | vertical-align: top; 220 | margin-right: 50px; 221 | } 222 | 223 | 224 | .nav-fields { 225 | margin-bottom: 40px; 226 | } 227 | 228 | .course-summary { 229 | cursor: pointer; 230 | } 231 | 232 | .chat { 233 | 234 | } 235 | 236 | img.dashboard-section { 237 | display: block; 238 | max-height: 300px; 239 | margin: 0 auto 50px auto; 240 | 241 | } 242 | 243 | .toggle-buttons { 244 | margin-bottom: 15px; 245 | } 246 | 247 | .graph-toggle { 248 | width: 30px; 249 | box-shadow: none; 250 | vertical-align: bottom; 251 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/common-styles/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/components-inputs-and-outputs/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {SearchBox} from "./search-box/search-box.component"; 8 | 9 | 10 | @Component({ 11 | selector:'app', 12 | template: ` 14 | ` 15 | }) 16 | export class App { 17 | 18 | onSearch(text) { 19 | alert(`From App Component: ${text}`); 20 | } 21 | 22 | } 23 | 24 | @NgModule({ 25 | declarations: [App, SearchBox], 26 | imports: [BrowserModule], 27 | bootstrap: [App] 28 | }) 29 | export class AppModule { 30 | 31 | } 32 | 33 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/components-inputs-and-outputs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 34 | 35 | 36 | 37 | 38 | 39 | 42 | 43 |
44 | 45 | 46 |
Really Understanding Angular - The Fundamentals
47 | 48 |
49 | 50 |
51 | 52 |
53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/components-inputs-and-outputs/search-box/search-box.component.css: -------------------------------------------------------------------------------- 1 | 2 | .btn-clear { 3 | background: #DE363F; 4 | color: white; 5 | font-weight: bold; 6 | border-radius: 4px; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/components-inputs-and-outputs/search-box/search-box.component.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/components-inputs-and-outputs/search-box/search-box.component.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, Input, EventEmitter, Output} from "@angular/core"; 3 | 4 | declare const module; 5 | 6 | @Component({ 7 | selector: 'search-box', 8 | moduleId: module.id, 9 | templateUrl: 'search-box.component.html', 10 | styleUrls: ['search-box.component.css'] 11 | }) 12 | export class SearchBox { 13 | 14 | @Input() 15 | text:string; 16 | 17 | @Output() 18 | search = new EventEmitter(); 19 | 20 | clear(box) { 21 | box.value = ''; 22 | } 23 | 24 | onSearch(searchText) { 25 | this.search.emit(searchText); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/components-inputs-and-outputs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ng-for/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {Hero} from "./hero"; 8 | import {Heroes} from "./heroes"; 9 | 10 | 11 | @Component({ 12 | selector: 'app', 13 | template: ` 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | ` 25 | }) 26 | export class App { 27 | 28 | 29 | } 30 | 31 | @NgModule({ 32 | declarations: [App, Hero, Heroes], 33 | imports: [BrowserModule], 34 | bootstrap: [App] 35 | }) 36 | export class AppModule { 37 | 38 | } 39 | 40 | platformBrowserDynamic().bootstrapModule(AppModule); 41 | 42 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ng-for/hero.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Directive, Input} from "@angular/core"; 3 | 4 | 5 | @Directive({ 6 | selector: 'hero', 7 | }) 8 | export class Hero { 9 | 10 | @Input() 11 | id: number; 12 | 13 | @Input() 14 | name:string; 15 | 16 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ng-for/heroes.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, ContentChildren, QueryList} from "@angular/core"; 3 | import {Hero} from "./hero"; 4 | 5 | 6 | const HEROES = [ 7 | {id: 1, name:'Superman'}, 8 | {id: 2, name:'Batman'}, 9 | {id: 5, name:'BatGirl'}, 10 | {id: 3, name:'Robin'}, 11 | {id: 4, name:'Flash'} 12 | ]; 13 | 14 | @Component({ 15 | selector:'heroes', 16 | template: ` 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
NameIndex
{{hero.name}}{{i}}
30 | ` 31 | }) 32 | export class Heroes { 33 | 34 | @ContentChildren(Hero) 35 | heroes: QueryList; 36 | 37 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ng-for/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Getting Started With Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Getting Started with Angular - The Fundamentals
48 |
Core Directives - *ngFor
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ng-for/lesson.css: -------------------------------------------------------------------------------- 1 | 2 | .lesson { 3 | 4 | text-align: left; 5 | 6 | } 7 | 8 | table td, table th { 9 | padding: 5px 8px; 10 | } 11 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ng-for/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngif/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | 8 | 9 | @Component({ 10 | selector: 'app', 11 | template: ` 12 | 13 |
Toggle Me
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ` 23 | }) 24 | export class App { 25 | 26 | show = true; 27 | hidden = false; 28 | visibility = 'visible'; 29 | 30 | toggleShow() { 31 | this.show = !this.show; 32 | } 33 | 34 | toggleHidden() { 35 | this.hidden = !this.hidden; 36 | } 37 | 38 | toggleVisible() { 39 | this.visibility = this.visibility == 'visible' ? 'hidden' : 'visible'; 40 | } 41 | 42 | } 43 | 44 | @NgModule({ 45 | declarations: [App], 46 | imports: [BrowserModule], 47 | bootstrap: [App] 48 | }) 49 | export class AppModule { 50 | 51 | } 52 | 53 | platformBrowserDynamic().bootstrapModule(AppModule); 54 | 55 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngif/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Getting Started With Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Getting Started with Angular - The Fundamentals
48 |
Core Directives - *ngIf
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngif/lesson.css: -------------------------------------------------------------------------------- 1 | 2 | .lesson { 3 | text-align: left; 4 | } 5 | 6 | 7 | .toggle-panel { 8 | background: #d00000; 9 | color: white; 10 | padding: 5px 10px; 11 | border:1px solid gray; 12 | border-radius: 4px; 13 | width: 100px; 14 | height: 50px; 15 | margin-bottom: 20px; 16 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngif/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngstyle-ngclass/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {Hero} from "./hero"; 8 | import {Heroes} from "./heroes"; 9 | 10 | 11 | @Component({ 12 | selector: 'app', 13 | template: ` 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ` 26 | }) 27 | export class App { 28 | 29 | 30 | } 31 | 32 | @NgModule({ 33 | declarations: [App, Hero, Heroes], 34 | imports: [BrowserModule], 35 | bootstrap: [App] 36 | }) 37 | export class AppModule { 38 | 39 | } 40 | 41 | platformBrowserDynamic().bootstrapModule(AppModule); 42 | 43 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngstyle-ngclass/hero.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Directive, Input} from "@angular/core"; 3 | 4 | 5 | @Directive({ 6 | selector: 'hero', 7 | }) 8 | export class Hero { 9 | 10 | @Input() 11 | id: number; 12 | 13 | @Input() 14 | name:string; 15 | 16 | @Input() 17 | marvel = false; 18 | 19 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngstyle-ngclass/heroes.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, ContentChildren, QueryList} from "@angular/core"; 3 | import {Hero} from "./hero"; 4 | 5 | export const BLUE = '#b13138'; 6 | export const RED = '#1976d2'; 7 | 8 | 9 | @Component({ 10 | selector:'heroes', 11 | template: ` 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 |
NameIndex
{{hero.name}}{{i}}
25 | ` 26 | }) 27 | export class Heroes { 28 | 29 | @ContentChildren(Hero) 30 | heroes: QueryList; 31 | 32 | get styles() { 33 | return { 34 | color: 'blue', 35 | 'text-decoration': 'underline' 36 | }; 37 | } 38 | 39 | classes(hero: Hero) { 40 | return { 41 | marvel:hero.marvel, 42 | hulk: hero.name === 'Hulk' 43 | }; 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngstyle-ngclass/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Getting Started With Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Getting Started with Angular - The Fundamentals
48 |
Core Directives - ngStyle and ngClass
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngstyle-ngclass/lesson.css: -------------------------------------------------------------------------------- 1 | 2 | .lesson { 3 | text-align: left; 4 | } 5 | 6 | table td, table th { 7 | padding: 5px 8px; 8 | } 9 | 10 | .marvel { 11 | background: #b13138; 12 | border: 1px solid gray; 13 | color: white; 14 | } 15 | 16 | .marvel.hulk { 17 | background: green; 18 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/core-directives-ngstyle-ngclass/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives-intro/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {CollapseOnClick} from "./collapse-on-click.directive"; 8 | 9 | 10 | 11 | @Component({ 12 | selector:'app', 13 | template: ` 14 | 15 |
17 | 18 | arrow_drop_down 19 | arrow_drop_up 20 | 21 |
22 | This page section is collapsible, double click it and it will collapse or expand. 23 |
24 |
25 | ` 26 | }) 27 | export class App { 28 | 29 | 30 | } 31 | 32 | @NgModule({ 33 | declarations: [App, CollapseOnClick], 34 | imports: [BrowserModule], 35 | bootstrap: [App] 36 | }) 37 | export class AppModule { 38 | 39 | } 40 | 41 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives-intro/collapse-on-click.directive.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Directive, HostBinding, HostListener, Input, Output, EventEmitter,Optional} from "@angular/core"; 3 | 4 | @Directive({ 5 | selector: '[collapse-on-click]', 6 | exportAs: "cp" 7 | }) 8 | export class CollapseOnClick { 9 | 10 | @Input("collapsed") 11 | isCollapsed = false; 12 | 13 | @Output("collapsed") 14 | collapsedOutput = new EventEmitter(); 15 | 16 | get collapsed() { 17 | return this.isCollapsed; 18 | } 19 | 20 | @HostListener('dblclick') 21 | onDblClick() { 22 | this.isCollapsed = !this.isCollapsed; 23 | this.collapsedOutput.emit(this.isCollapsed); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives-intro/directives-intro.css: -------------------------------------------------------------------------------- 1 | 2 | .lesson.lesson-directives-intro { 3 | max-width: 400px; 4 | cursor: pointer; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives-intro/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 36 | 37 | 38 | 39 | 40 | 41 | 44 | 45 |
46 | 47 | 48 |
Getting Started With Angular
49 |
50 | 51 |
52 | 53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives-intro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {ShowOneContainer} from "./show-one-container"; 8 | import {ShowOne} from "./show-one"; 9 | import {ShowOneTrigger} from "./show-one-trigger"; 10 | 11 | 12 | @Component({ 13 | selector: 'app', 14 | template: ` 15 | 16 |
17 | 18 |
    19 |
  • Superman
  • 20 |
  • Batman
  • 21 |
  • Flash
  • 22 |
23 | 24 |
25 | 26 |
27 | 28 |
29 | 30 |
31 | 32 |
33 | 34 |
35 | 36 |
37 | 38 | ` 39 | }) 40 | export class App { 41 | 42 | } 43 | 44 | @NgModule({ 45 | declarations: [App, ShowOne, ShowOneContainer, ShowOneTrigger], 46 | imports: [BrowserModule], 47 | bootstrap: [App] 48 | }) 49 | export class AppModule { 50 | 51 | } 52 | 53 | platformBrowserDynamic().bootstrapModule(AppModule); 54 | 55 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Getting Started With Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Getting Started with Angular - The Fundamentals
48 |
Directives Essentials
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives/lesson.css: -------------------------------------------------------------------------------- 1 | 2 | .lesson { 3 | text-align: left; 4 | } 5 | 6 | 7 | .toggle-panel { 8 | background: #d00000; 9 | color: white; 10 | padding: 5px 10px; 11 | border:1px solid gray; 12 | border-radius: 4px; 13 | width: 100px; 14 | height: 50px; 15 | margin-bottom: 20px; 16 | } 17 | 18 | .logo { 19 | background-repeat: no-repeat; 20 | background-size: 80px; 21 | background-position-x: center; 22 | background-position-y: center; 23 | height: 50px; 24 | margin: 0 auto; 25 | padding: 30px 0; 26 | } 27 | 28 | .superman { 29 | background-image: url('/images/superman.png'); 30 | } 31 | 32 | .batman { 33 | background-image: url('/images/batman.jpg'); 34 | } 35 | 36 | .flash { 37 | background-image: url('/images/flash.svg'); 38 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives/show-one-container.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Directive, ContentChildren, QueryList} from "@angular/core"; 4 | import {ShowOne} from "./show-one"; 5 | import {ShowOneTrigger} from "./show-one-trigger"; 6 | 7 | 8 | @Directive({ 9 | selector: '[showOneContainer]' 10 | }) 11 | export class ShowOneContainer { 12 | 13 | triggers: ShowOneTrigger[] = []; 14 | 15 | @ContentChildren(ShowOne) 16 | items: QueryList; 17 | 18 | add(trigger: ShowOneTrigger) { 19 | this.triggers.push(trigger); 20 | } 21 | 22 | show(id:string) { 23 | this.items.forEach(item => item.active = item.id == id); 24 | this.triggers.forEach( 25 | (trigger:ShowOneTrigger) => trigger.active = trigger.id == id); 26 | } 27 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives/show-one-trigger.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Directive, HostListener, HostBinding, Input} from "@angular/core"; 4 | import {ShowOneContainer} from "./show-one-container"; 5 | 6 | 7 | @Directive({ 8 | selector: '[showOneTrigger]' 9 | }) 10 | export class ShowOneTrigger { 11 | 12 | @Input("showOneTrigger") 13 | id: string; 14 | 15 | @Input() 16 | active = false; 17 | 18 | constructor(private showOneContainer: ShowOneContainer) { 19 | showOneContainer.add(this); 20 | } 21 | 22 | @HostListener('click') 23 | click() { 24 | this.showOneContainer.show(this.id); 25 | } 26 | 27 | @HostBinding('class.selected') 28 | get selected() { 29 | return this.active; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives/show-one.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Directive, HostBinding, Input} from "@angular/core"; 4 | 5 | 6 | @Directive({ 7 | selector: '[showOne]' 8 | }) 9 | export class ShowOne { 10 | 11 | @Input("showOne") 12 | id:string; 13 | 14 | @Input() 15 | active = false; 16 | 17 | @HostBinding('hidden') 18 | get hidden() { 19 | return !this.active; 20 | } 21 | 22 | 23 | 24 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/directives/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/exercise-color-sample/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {ColorSample} from "./color-sample"; 8 | 9 | @Component({ 10 | selector:'app', 11 | template: ` 12 | ` 14 | }) 15 | export class App { 16 | 17 | color: string; 18 | 19 | onType(newColor) { 20 | this.color = newColor; 21 | } 22 | 23 | } 24 | 25 | @NgModule({ 26 | declarations: [App, ColorSample], 27 | imports: [BrowserModule], 28 | bootstrap: [App] 29 | }) 30 | export class AppModule { 31 | 32 | } 33 | 34 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/exercise-color-sample/color-sample.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component, Input} from "@angular/core"; 4 | 5 | @Component({ 6 | selector:'color-sample', 7 | template: `
` 9 | }) 10 | export class ColorSample { 11 | 12 | @Input() 13 | color:string; 14 | 15 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/exercise-color-sample/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Really Understanding Angular - The Fundamentals
48 | 49 |
50 | 51 |
52 | 53 |
54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/exercise-color-sample/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-model-driven/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, NgModule} from "@angular/core"; 3 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 4 | import {BrowserModule} from "@angular/platform-browser"; 5 | import {FormGroup, FormControl, Validators, FormBuilder, ReactiveFormsModule} from "@angular/forms"; 6 | import {Lesson, StudentLevel} from "./lesson"; 7 | import "rxjs/Rx"; 8 | import {validateDuration} from "./validateDuration"; 9 | 10 | 11 | @Component({ 12 | selector:'app', 13 | template: ` 14 | 15 |

Model Driven Forms

16 | 17 |
18 |
19 | 20 | 21 |
23 | field is mandatory 24 |
25 |
27 | This title already exists ! 28 |
29 |
30 |
31 | 32 | 33 |
34 |
35 | 36 | 37 |
38 |
39 | 40 |
41 |
42 | 43 | 44 | 45 | ` 46 | }) 47 | export class App { 48 | 49 | myForm: FormGroup; 50 | 51 | duration = new FormControl(10, [validateDuration]); 52 | 53 | lesson = new Lesson( 54 | "Title goes here", 55 | 0, 56 | "Description goes here", 57 | "Transcript goes here", 58 | StudentLevel.BEGINNER 59 | ); 60 | 61 | constructor(fb: FormBuilder) { 62 | 63 | this.myForm = fb.group({ 64 | title: ['This is the title', [ 65 | Validators.minLength(5) ] 66 | ], 67 | duration: this.duration, 68 | description: ['description goes here',[Validators.required]] 69 | }); 70 | 71 | 72 | 73 | 74 | 75 | 76 | this.myForm.valueChanges 77 | .filter(() => this.myForm.valid) 78 | .map(value => new Lesson(value.title, value.duration, 79 | value.description,"",StudentLevel.BEGINNER)) 80 | .do(formValue => console.log("Valid Form Value:", formValue)) 81 | .subscribe( 82 | lesson => this.lesson = lesson 83 | ); 84 | 85 | } 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | partialUpdate() { 95 | this.myForm.patchValue({ 96 | title: "Set Form Values", 97 | duration: 5 98 | }); 99 | } 100 | 101 | fullUpdate() { 102 | this.myForm.setValue({ 103 | title: "Set Form Values", 104 | description: "new description" 105 | }); 106 | } 107 | 108 | reset() { 109 | this.myForm.reset(); 110 | } 111 | 112 | 113 | } 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | @NgModule({ 140 | declarations: [App], 141 | imports: [BrowserModule, ReactiveFormsModule], 142 | bootstrap: [App] 143 | }) 144 | export class AppModule { 145 | 146 | } 147 | 148 | platformBrowserDynamic().bootstrapModule(AppModule); 149 | 150 | 151 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-model-driven/checkIfTitleExists.ts: -------------------------------------------------------------------------------- 1 | 2 | import {FormControl} from "@angular/forms"; 3 | import {HTTP_PROVIDERS, Http, URLSearchParams} from "@angular/http"; 4 | import {Observable} from "rxjs/Rx"; 5 | 6 | 7 | /* 8 | * 9 | * Asynchronous validators with Observables are still being worked on by the Angular Team. 10 | * 11 | * This will the subject of a future lesson. 12 | * 13 | * */ 14 | 15 | export function checkIfTitleExists(http:Http, ctrl: FormControl): Observable { 16 | 17 | const search: URLSearchParams = new URLSearchParams(); 18 | search.set('search', ctrl.value); 19 | 20 | return http.get('/lessons', {search:search}) 21 | .do(() => console.log('request sent ...')) 22 | .map(res => { 23 | 24 | const lesson = res.json(); 25 | 26 | return !lesson ? null : { 27 | titleExists: { 28 | valid:false 29 | } 30 | }; 31 | }); 32 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-model-driven/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 | 48 |
49 | 50 |
51 | 52 | 53 |
54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-model-driven/lesson.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export enum StudentLevel { 4 | BEGINNER, 5 | ADVANCED 6 | } 7 | 8 | 9 | export class Lesson { 10 | 11 | id:string; 12 | 13 | constructor(public title:string, duration:number, public description:string, 14 | public transcript:string, private _level:StudentLevel) { 15 | 16 | } 17 | 18 | set level(level:string) { 19 | console.log("setting lesson level..."); 20 | this._level = StudentLevel[level]; 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-model-driven/number-field.component.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component} from "@angular/core"; 4 | import {Component, Provider, forwardRef} from "@angular/core"; 5 | import {ControlValueAccessor, NG_VALUE_ACCESSOR, CORE_DIRECTIVES} from "@angular/common"; 6 | 7 | 8 | export const NUMBER_FIELD_CONTROL_VALUE_ACCESSOR: any = { 9 | provide: NG_VALUE_ACCESSOR, 10 | useExisting: forwardRef(() => NumberField), 11 | multi: true 12 | }; 13 | 14 | 15 | @Component({ 16 | selector: 'number-field', 17 | providers: [NUMBER_FIELD_CONTROL_VALUE_ACCESSOR], 18 | template: `` 19 | }) 20 | export class NumberField implements ControlValueAccessor { 21 | 22 | numValue = 0; 23 | 24 | private _onTouchedCallback = (value:number) => {}; 25 | 26 | private _onChangeCallback = (value:number) => {}; 27 | 28 | 29 | valueAccessor(): any { return this.numValue; }; 30 | 31 | set value(v: any) { 32 | if (v !== this.numValue) { 33 | this.numValue = v; 34 | this._onChangeCallback(v); 35 | } 36 | } 37 | 38 | writeValue(value):void { 39 | this.numValue = value; 40 | } 41 | 42 | registerOnChange(callback) { 43 | this._onChangeCallback = callback; 44 | } 45 | 46 | registerOnTouched(callback) { 47 | this._onTouchedCallback = callback; 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-model-driven/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-model-driven/validateDuration.ts: -------------------------------------------------------------------------------- 1 | 2 | import {FormControl} from "@angular/forms"; 3 | 4 | 5 | export function validateDuration(ctrl: FormControl) { 6 | 7 | const numValue = parseInt(ctrl.value); 8 | 9 | const valid = numValue && numValue < 10; 10 | 11 | return valid ? null : { 12 | validateDuration: { 13 | valid:false 14 | } 15 | }; 16 | 17 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-signup-exercise/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | import {FormsModule, FormControl, ReactiveFormsModule} from "@angular/forms"; 7 | import {confirmPassword} from "./confirmPassword"; 8 | 9 | 10 | @Component({ 11 | selector:'app', 12 | template: ` 13 | 14 |

Sign Up To Our Website

15 | 16 |
17 | 18 |
19 | 20 | 22 |
name is mandatory
24 |
25 |
26 | 27 | 29 |
email is mandatory
31 |
32 |
33 | 34 | 36 |
37 |
38 | 39 | 40 |
41 | 42 |

43 | 45 |

46 | 47 |
48 | 49 |
50 |

Form Value:

51 | {{ f.value | json }} 52 |
53 | 54 | ` 55 | }) 56 | export class App { 57 | 58 | signup = {}; 59 | 60 | confirm = new FormControl('', [confirmPassword.bind(undefined, this.signup)]); 61 | 62 | signUp() { 63 | console.log("Sign Up Data:" , this.signup); 64 | } 65 | 66 | 67 | } 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | @NgModule({ 89 | declarations: [App], 90 | imports: [BrowserModule, FormsModule, ReactiveFormsModule], 91 | bootstrap: [App] 92 | }) 93 | export class AppModule { 94 | 95 | } 96 | 97 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-signup-exercise/confirmPassword.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | export function confirmPassword(signup, ctrl) { 5 | 6 | const valid = signup.password && signup.password === ctrl.value; 7 | 8 | return valid ? null : { 9 | confirmPassword:false 10 | }; 11 | 12 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-signup-exercise/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 | 48 |
49 | 50 |
51 | 52 | 53 |
54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-signup-exercise/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-template-driven/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, NgModule} from "@angular/core"; 3 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 4 | import {BrowserModule} from "@angular/platform-browser"; 5 | import {Lesson} from "./lesson"; 6 | import {FormsModule} from "@angular/forms"; 7 | import {DurationValidator} from "./validate-duration.directive"; 8 | 9 | 10 | @Component({ 11 | selector:'app', 12 | template: ` 13 | 14 |

Create Lesson Form - Template Driven

15 | 16 |
17 | 18 |
19 | Summary 20 |
21 | 22 | 24 |
25 | field is mandatory
26 |
min 5 chars
27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 | 35 | Beginner 36 | 37 | Advanced 38 |
39 |
40 | 41 |
42 | Long Text Fields 43 |
44 | 45 | 46 |
47 |
48 | 49 |

50 | 52 |

53 | 54 |
55 | 56 |
57 |

Form Value:

58 | {{ f.value | json }} 59 |
60 | 61 | 62 | ` 63 | }) 64 | export class App { 65 | 66 | lesson = new Lesson(); 67 | 68 | createLesson(form) { 69 | console.log("Lesson Value:", this.lesson, form); 70 | debugger; 71 | } 72 | 73 | 74 | summaryStatus(summary) { 75 | return { 76 | color: !summary.valid && !summary.pristine ? 'red' : 'black' 77 | } 78 | } 79 | 80 | } 81 | 82 | 83 | @NgModule({ 84 | declarations: [App, DurationValidator], 85 | imports: [BrowserModule, FormsModule], 86 | bootstrap: [App] 87 | }) 88 | export class AppModule { 89 | 90 | } 91 | 92 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-template-driven/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
48 | 49 |
50 | 51 | 52 |
53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-template-driven/lesson.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export enum StudentLevel { 4 | BEGINNER, 5 | ADVANCED 6 | } 7 | 8 | 9 | 10 | export class Lesson { 11 | 12 | public id:string; 13 | 14 | constructor( 15 | public title = "", 16 | public duration = 0, 17 | public description = "", 18 | private _level = StudentLevel.BEGINNER) { 19 | 20 | } 21 | 22 | set level(level:string) { 23 | console.log("setting lesson level..."); 24 | this._level = StudentLevel[level]; 25 | } 26 | 27 | get level() { 28 | return StudentLevel[this._level]; 29 | } 30 | 31 | 32 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-template-driven/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-template-driven/validate-duration.directive.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Directive, forwardRef} from "@angular/core"; 3 | import {Validator, FormControl, NG_VALIDATORS} from "@angular/forms"; 4 | import {validateDuration} from "./validateDuration"; 5 | 6 | 7 | export const MIN_LENGTH_VALIDATOR = { 8 | provide: NG_VALIDATORS, 9 | multi:true, 10 | useExisting: forwardRef(() => DurationValidator) 11 | }; 12 | 13 | 14 | 15 | @Directive({ 16 | selector: '[duration][ngModel]', 17 | providers: [MIN_LENGTH_VALIDATOR] 18 | }) 19 | export class DurationValidator implements Validator { 20 | 21 | 22 | validate(c: FormControl): {[key:string]:any} { 23 | return validateDuration(c); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/forms-template-driven/validateDuration.ts: -------------------------------------------------------------------------------- 1 | 2 | import {FormControl} from '@angular/forms'; 3 | 4 | 5 | export function validateDuration(ctrl: FormControl) { 6 | 7 | const valid = ctrl.value && parseInt(ctrl.value) && parseInt(ctrl.value) < 10; 8 | 9 | return valid ? null : { 10 | validateDuration: { 11 | valid:false 12 | } 13 | }; 14 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/introduction-to-pipes/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, NgModule} from "@angular/core"; 3 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 4 | import {BrowserModule} from "@angular/platform-browser"; 5 | import {SortPipe} from "./sort.pipe"; 6 | 7 | 8 | @Component({ 9 | selector: 'app', 10 | template: ` 11 | 12 |
13 | 14 |
15 | 16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 | 24 |
25 | 26 |
27 | 28 |
29 | 30 |
31 | 32 |
33 | 34 |
35 | 36 |
37 | 38 |
39 | 40 |
41 | 42 |
43 | 44 | ` 45 | }) 46 | export class App { 47 | 48 | 49 | message = 'Hello World !'; 50 | 51 | date = new Date(); 52 | 53 | pi = 3.14159265359; 54 | 55 | percentage = 0.0234; 56 | 57 | amount = 12.1234; 58 | 59 | data = ['A', 'B', 'H', 'C']; 60 | 61 | } 62 | 63 | @NgModule({ 64 | declarations: [App, SortPipe], 65 | imports: [BrowserModule], 66 | bootstrap: [App] 67 | }) 68 | export class AppModule { 69 | 70 | } 71 | 72 | platformBrowserDynamic().bootstrapModule(AppModule); 73 | 74 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/introduction-to-pipes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Getting Started With Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Getting Started with Angular - The Fundamentals
48 |
Introduction to Pipes
49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/introduction-to-pipes/lesson.css: -------------------------------------------------------------------------------- 1 | 2 | .lesson { 3 | text-align: left; 4 | } 5 | 6 | .pipe-example { 7 | margin-bottom: 10px; 8 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/introduction-to-pipes/sort.pipe.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Pipe, PipeTransform} from "@angular/core"; 3 | 4 | @Pipe({ 5 | name: 'sort' 6 | }) 7 | export class SortPipe implements PipeTransform { 8 | 9 | transform(array: any[], args): any[] { 10 | 11 | let sorted = array.sort(); 12 | 13 | if (args.length > 0 && args === 'DESC' ) { 14 | sorted = sorted.reverse(); 15 | } 16 | 17 | return sorted; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/introduction-to-pipes/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, NgModule} from "@angular/core"; 3 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 4 | import {BrowserModule} from "@angular/platform-browser"; 5 | import {HttpModule} from "@angular/http"; 6 | import "rxjs/Rx"; 7 | import {LessonsService} from "./lessons.service"; 8 | import {LessonsList} from "./lessons-list.component"; 9 | 10 | 11 | @Component({ 12 | selector:'app', 13 | template: ` 14 | 15 | 17 | 18 | 19 | 20 | ` 21 | }) 22 | export class App { 23 | 24 | constructor(private lessonsService: LessonsService) { 25 | 26 | } 27 | 28 | } 29 | 30 | @NgModule({ 31 | declarations: [App, LessonsList], 32 | imports: [BrowserModule, HttpModule], 33 | bootstrap: [App], 34 | providers: [LessonsService] 35 | }) 36 | export class AppModule { 37 | 38 | } 39 | 40 | 41 | 42 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Introduction To Angular
48 | 49 |
50 | 51 |
52 | 53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons-list.component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | var core_1 = require("@angular/core"); 12 | var lessons_service_1 = require("./lessons.service"); 13 | var LessonsList = (function () { 14 | function LessonsList(lessonsService) { 15 | this.lessonsService = lessonsService; 16 | this.lessons = []; 17 | } 18 | __decorate([ 19 | core_1.Input(), 20 | __metadata('design:type', Object) 21 | ], LessonsList.prototype, "lessons", void 0); 22 | LessonsList = __decorate([ 23 | core_1.Component({ 24 | selector: 'lessons-list', 25 | template: "\n \n \n \n \n \n \n
\n \n \n {{lesson.description}} \n \n \n
\n\n " 26 | }), 27 | __metadata('design:paramtypes', [lessons_service_1.LessonsService]) 28 | ], LessonsList); 29 | return LessonsList; 30 | }()); 31 | exports.LessonsList = LessonsList; 32 | //# sourceMappingURL=lessons-list.component.js.map -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons-list.component.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"lessons-list.component.js","sourceRoot":"","sources":["lessons-list.component.ts"],"names":[],"mappings":";;;;;;;;;;AACA,qBAA+B,eAAe,CAAC,CAAA;AAC/C,gCAA6B,mBAAmB,CAAC,CAAA;AAuBjD;IAOI,qBAAoB,cAA8B;QAA9B,mBAAc,GAAd,cAAc,CAAgB;QAHlD,YAAO,GAAG,EAAE,CAAC;IAKb,CAAC;IAND;QAAC,YAAK,EAAE;;gDAAA;IAvBZ;QAAC,gBAAS,CAAC;YACP,QAAQ,EAAC,cAAc;YACvB,QAAQ,EAAE,ynBAgBL;SACR,CAAC;;mBAAA;IAeF,kBAAC;AAAD,CAAC,AAdD,IAcC;AAdY,mBAAW,cAcvB,CAAA"} -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons-list.component.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, Input} from "@angular/core"; 3 | import {LessonsService} from "./lessons.service"; 4 | 5 | 6 | @Component({ 7 | selector:'lessons-list', 8 | template: ` 9 | 10 | 11 | 15 | 18 | 21 | 22 |
12 | 14 | 16 | {{lesson.description}} 17 | 19 | 20 |
23 | 24 | ` 25 | }) 26 | export class LessonsList { 27 | 28 | 29 | @Input() 30 | lessons = []; 31 | 32 | 33 | constructor(private lessonsService: LessonsService) { 34 | 35 | } 36 | 37 | 38 | 39 | 40 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | exports.lessonsData = [ 3 | { 4 | id: 1, 5 | url: 'angular2-hello-world-write-first-application', 6 | description: 'Build Your First App - Hello World Step By Step', 7 | duration: '2:49', 8 | tags: "BEGINNER" 9 | }, 10 | { 11 | id: 2, 12 | url: 'angular2-build-your-first-component', 13 | description: 'Building Your First Component', 14 | duration: '2:07', 15 | tags: "BEGINNER" 16 | }, 17 | { 18 | id: 3, 19 | url: 'angular2-passing-data-to-component-using-input', 20 | description: 'Component @Input - How To Pass Input Data To a Component', 21 | duration: '2:33', 22 | tags: "BEGINNER" 23 | }, 24 | { 25 | id: 4, 26 | url: 'angular2-component-events', 27 | description: 'Component Events - Using @Output to create custom events', 28 | duration: '4:44', 29 | tags: "BEGINNER" 30 | }, 31 | { 32 | id: 5, 33 | url: 'angular2-component-templates-internal-vs-external', 34 | description: 'Component Templates - Inline Vs External', 35 | duration: '2:55', 36 | tags: "BEGINNER" 37 | }, 38 | { 39 | id: 6, 40 | url: 'angular2-components-styling-component-isolation', 41 | description: 'Styling Components - Learn About Component Style Isolation', 42 | duration: '3:27', 43 | tags: "BEGINNER" 44 | }, 45 | { 46 | id: 7, 47 | url: 'angular2-components-component-interaction', 48 | description: 'Component Interaction - Extended Components Example', 49 | duration: '5:27', 50 | tags: "BEGINNER" 51 | }, 52 | { 53 | id: 8, 54 | url: 'angular2-components-exercise', 55 | description: 'Components Exercise !', 56 | duration: '1:26', 57 | tags: "BEGINNER" 58 | }, 59 | { 60 | id: 9, 61 | url: 'angular2-components-exercise-solution', 62 | description: 'Components Exercise Solution Inside', 63 | duration: '2:08', 64 | tags: "BEGINNER" 65 | } 66 | ]; 67 | //# sourceMappingURL=lessons.js.map -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"lessons.js","sourceRoot":"","sources":["lessons.ts"],"names":[],"mappings":";AAAa,mBAAW,GAAG;IACvB;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,8CAA8C;QACnD,WAAW,EAAC,iDAAiD;QAC7D,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;IACD;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,qCAAqC;QAC1C,WAAW,EAAC,+BAA+B;QAC3C,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;IACD;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,gDAAgD;QACrD,WAAW,EAAC,0DAA0D;QACtE,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;IACD;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,2BAA2B;QAChC,WAAW,EAAC,0DAA0D;QACtE,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;IACD;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,mDAAmD;QACxD,WAAW,EAAC,0CAA0C;QACtD,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;IACD;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,iDAAiD;QACtD,WAAW,EAAC,4DAA4D;QACxE,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;IACD;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,2CAA2C;QAChD,WAAW,EAAC,qDAAqD;QACjE,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;IACD;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,8BAA8B;QACnC,WAAW,EAAC,uBAAuB;QACnC,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;IACD;QACI,EAAE,EAAE,CAAC;QACL,GAAG,EAAE,uCAAuC;QAC5C,WAAW,EAAC,qCAAqC;QACjD,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAC,UAAU;KAClB;CACJ,CAAC"} -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons.module.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import {NgModule} from "@angular/core"; 5 | import {LessonsList} from "./lessons-list.component"; 6 | import {LessonsService} from "./lessons.service"; 7 | import {CommonModule} from "@angular/common"; 8 | 9 | @NgModule({ 10 | imports: [CommonModule], 11 | declarations: [LessonsList], 12 | exports: [LessonsList], 13 | providers: [LessonsService] 14 | }) 15 | export class LessonsModule { 16 | 17 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | var core_1 = require("@angular/core"); 12 | var http_1 = require("@angular/http"); 13 | var xhr_headers_1 = require("./xhr-headers"); 14 | var LessonsService = (function () { 15 | function LessonsService(http) { 16 | this.http = http; 17 | this.lessons = []; 18 | this.loadLessons(); 19 | } 20 | LessonsService.prototype.loadLessons = function () { 21 | var _this = this; 22 | this.http.get('/lessons') 23 | .map(function (res) { return res.json(); }) 24 | .subscribe(function (lessons) { return _this.lessons = lessons; }, function (err) { return console.error(err); }); 25 | }; 26 | LessonsService.prototype.createLesson = function (description) { 27 | console.log("creating lesson ..."); 28 | var lesson = { description: description }; 29 | this.lessons.push(lesson); 30 | this.http.post('/lessons', JSON.stringify(lesson), xhr_headers_1.xhrHeaders()) 31 | .subscribe(function () { }, function (err) { return console.error(err); }); 32 | }; 33 | LessonsService.prototype.delete = function (lessonId) { 34 | console.log("deleting lesson ..."); 35 | var index = this.lessons.findIndex(function (lesson) { return lesson.id === lessonId; }); 36 | this.lessons.splice(index, 1); 37 | this.http.delete("/lessons/" + lessonId, xhr_headers_1.xhrHeaders()) 38 | .subscribe(function () { }, function (err) { return console.error(err); }); 39 | }; 40 | LessonsService = __decorate([ 41 | core_1.Injectable(), 42 | __metadata('design:paramtypes', [http_1.Http]) 43 | ], LessonsService); 44 | return LessonsService; 45 | }()); 46 | exports.LessonsService = LessonsService; 47 | //# sourceMappingURL=lessons.service.js.map -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons.service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"lessons.service.js","sourceRoot":"","sources":["lessons.service.ts"],"names":[],"mappings":";;;;;;;;;;AACA,qBAAyB,eAAe,CAAC,CAAA;AACzC,qBAAmB,eAAe,CAAC,CAAA;AACnC,4BAAyB,eAAe,CAAC,CAAA;AAIzC;IAII,wBAAoB,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;QAF9B,YAAO,GAAG,EAAE,CAAC;QAGT,IAAI,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;IAED,oCAAW,GAAX;QAAA,iBAOC;QANG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;aACpB,GAAG,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,IAAI,EAAE,EAAV,CAAU,CAAC;aACtB,SAAS,CACN,UAAA,OAAO,IAAI,OAAA,KAAI,CAAC,OAAO,GAAG,OAAO,EAAtB,CAAsB,EACjC,UAAA,GAAG,IAAI,OAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAlB,CAAkB,CAC5B,CAAC;IACV,CAAC;IAED,qCAAY,GAAZ,UAAa,WAAW;QACpB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,IAAM,MAAM,GAAG,EAAC,aAAA,WAAW,EAAC,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,wBAAU,EAAE,CAAC;aAC3D,SAAS,CACN,cAAO,CAAC,EACR,UAAA,GAAG,IAAI,OAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAlB,CAAkB,CAC5B,CAAC;IACV,CAAC;IAED,+BAAM,GAAN,UAAO,QAAQ;QACX,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,IAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAChC,UAAA,MAAM,IAAI,OAAA,MAAM,CAAC,EAAE,KAAK,QAAQ,EAAtB,CAAsB,CACnC,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAY,QAAU,EAAE,wBAAU,EAAE,CAAC;aACjD,SAAS,CACN,cAAO,CAAC,EACR,UAAA,GAAG,IAAI,OAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAlB,CAAkB,CAC5B,CAAC;IACV,CAAC;IAxCL;QAAC,iBAAU,EAAE;;sBAAA;IA0Cb,qBAAC;AAAD,CAAC,AAzCD,IAyCC;AAzCY,sBAAc,iBAyC1B,CAAA"} -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons.service.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Injectable} from "@angular/core"; 3 | import {Http} from "@angular/http"; 4 | import {xhrHeaders} from "./xhr-headers"; 5 | 6 | 7 | @Injectable() 8 | export class LessonsService { 9 | 10 | lessons = []; 11 | 12 | constructor(private http: Http) { 13 | this.loadLessons(); 14 | } 15 | 16 | loadLessons() { 17 | this.http.get('/lessons') 18 | .map(res => res.json()) 19 | .subscribe( 20 | lessons => this.lessons = lessons, 21 | err => console.error(err) 22 | ); 23 | } 24 | 25 | createLesson(description) { 26 | console.log("creating lesson ..."); 27 | const lesson = {description}; 28 | this.lessons.push(lesson); 29 | this.http.post('/lessons', JSON.stringify(lesson), xhrHeaders()) 30 | .subscribe( 31 | () => {}, 32 | err => console.error(err) 33 | ); 34 | } 35 | 36 | delete(lessonId) { 37 | console.log("deleting lesson ..."); 38 | const index = this.lessons.findIndex( 39 | lesson => lesson.id === lessonId 40 | ); 41 | this.lessons.splice(index, 1); 42 | this.http.delete(`/lessons/${lessonId}`, xhrHeaders()) 43 | .subscribe( 44 | () => {}, 45 | err => console.error(err) 46 | ); 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/lessons.ts: -------------------------------------------------------------------------------- 1 | export const lessonsData = [ 2 | { 3 | id: 1, 4 | url: 'angular2-hello-world-write-first-application', 5 | description:'Build Your First App - Hello World Step By Step', 6 | duration: '2:49', 7 | tags:"BEGINNER" 8 | }, 9 | { 10 | id: 2, 11 | url: 'angular2-build-your-first-component', 12 | description:'Building Your First Component', 13 | duration: '2:07', 14 | tags:"BEGINNER" 15 | }, 16 | { 17 | id: 3, 18 | url: 'angular2-passing-data-to-component-using-input', 19 | description:'Component @Input - How To Pass Input Data To a Component', 20 | duration: '2:33', 21 | tags:"BEGINNER" 22 | }, 23 | { 24 | id: 4, 25 | url: 'angular2-component-events', 26 | description:'Component Events - Using @Output to create custom events', 27 | duration: '4:44', 28 | tags:"BEGINNER" 29 | }, 30 | { 31 | id: 5, 32 | url: 'angular2-component-templates-internal-vs-external', 33 | description:'Component Templates - Inline Vs External', 34 | duration: '2:55', 35 | tags:"BEGINNER" 36 | }, 37 | { 38 | id: 6, 39 | url: 'angular2-components-styling-component-isolation', 40 | description:'Styling Components - Learn About Component Style Isolation', 41 | duration: '3:27', 42 | tags:"BEGINNER" 43 | }, 44 | { 45 | id: 7, 46 | url: 'angular2-components-component-interaction', 47 | description:'Component Interaction - Extended Components Example', 48 | duration: '5:27', 49 | tags:"BEGINNER" 50 | }, 51 | { 52 | id: 8, 53 | url: 'angular2-components-exercise', 54 | description:'Components Exercise !', 55 | duration: '1:26', 56 | tags:"BEGINNER" 57 | }, 58 | { 59 | id: 9, 60 | url: 'angular2-components-exercise-solution', 61 | description:'Components Exercise Solution Inside', 62 | duration: '2:08', 63 | tags:"BEGINNER" 64 | } 65 | ]; -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/xhr-headers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var http_1 = require("@angular/http"); 3 | function xhrHeaders() { 4 | var headers = new http_1.Headers(); 5 | headers.append('Content-Type', 'application/json; charset=utf-8'); 6 | headers.append('X-Requested-With', 'XMLHttpRequest'); 7 | return { headers: headers }; 8 | } 9 | exports.xhrHeaders = xhrHeaders; 10 | //# sourceMappingURL=xhr-headers.js.map -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/xhr-headers.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"xhr-headers.js","sourceRoot":"","sources":["xhr-headers.ts"],"names":[],"mappings":";AACA,qBAAsB,eAAe,CAAC,CAAA;AAEtC;IACI,IAAM,OAAO,GAAG,IAAI,cAAO,EAAE,CAAC;IAC9B,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;IAClE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAC,gBAAgB,CAAC,CAAC;IACpD,MAAM,CAAC,EAAC,SAAA,OAAO,EAAC,CAAC;AACrB,CAAC;AALe,kBAAU,aAKzB,CAAA"} -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/modules-intro/xhr-headers.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Headers} from "@angular/http"; 3 | 4 | export function xhrHeaders() { 5 | const headers = new Headers(); 6 | headers.append('Content-Type', 'application/json; charset=utf-8'); 7 | headers.append('X-Requested-With','XMLHttpRequest'); 8 | return {headers}; 9 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-exercise/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {RouterModule} from "@angular/router"; 8 | import {routeConfig} from "./router-config"; 9 | import {DashboardHeader} from "./dashboard-header"; 10 | import {PageViewsByBrowserWidget} from "./page-views-by-browser.component"; 11 | import {PageViewsPieChartWidget} from "./page-views-pie-chart.component"; 12 | import {ImpressionsByCountryWidget} from "./impresssions-by-country.component"; 13 | 14 | 15 | @Component({ 16 | selector:'app', 17 | template: ` 18 | 19 | 24 | 25 |
26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 |
42 | 43 |
44 | 45 | ` 46 | }) 47 | export class App { 48 | 49 | 50 | 51 | } 52 | 53 | 54 | @NgModule({ 55 | declarations: [App, DashboardHeader, PageViewsByBrowserWidget, PageViewsPieChartWidget, ImpressionsByCountryWidget], 56 | imports: [BrowserModule, RouterModule.forRoot(routeConfig)], 57 | bootstrap: [App] 58 | }) 59 | export class AppModule { 60 | 61 | } 62 | 63 | platformBrowserDynamic().bootstrapModule(AppModule); 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-exercise/dashboard-header.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {Router} from "@angular/router"; 3 | 4 | @Component({ 5 | selector: 'dashboard', 6 | template: ` 7 | 8 |

Dashboard

9 |

click on a checkbox to include a section

10 | 11 |
12 | Graph 1 14 | 15 | Graph 2 17 | 18 | Graph 3 20 |
21 | 22 | ` 23 | }) 24 | export class DashboardHeader { 25 | 26 | 27 | constructor(private router: Router) { 28 | 29 | } 30 | 31 | setGraphs(g1, g2, g3) { 32 | console.log(g1, g2, g3); 33 | 34 | let sections = ""; 35 | 36 | if (g1) { 37 | sections += "section1:section1"; 38 | } 39 | 40 | if (g2) { 41 | if (sections) { 42 | sections += "//"; 43 | } 44 | sections += "section2:section2"; 45 | } 46 | 47 | if (g3) { 48 | if (sections) { 49 | sections += "//"; 50 | } 51 | sections += "section3:section3"; 52 | } 53 | let url = '/home'; 54 | 55 | if (sections) { 56 | url += `(${sections})`; 57 | } 58 | 59 | console.log(url); 60 | this.router.navigateByUrl(url); 61 | 62 | } 63 | 64 | 65 | 66 | 67 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-exercise/impresssions-by-country.component.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component} from "@angular/core"; 4 | 5 | @Component({ 6 | selector: 'dashboard-section', 7 | template: ` 8 | 9 |
10 |

Impressions By Country

11 | 13 |
14 | 15 | ` 16 | }) 17 | export class ImpressionsByCountryWidget { 18 | 19 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-exercise/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-exercise/page-views-by-browser.component.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component} from "@angular/core"; 4 | 5 | @Component({ 6 | selector: 'dashboard-section', 7 | template: ` 8 | 9 |
10 |

Page Views By Browser

11 | 13 |
14 | 15 | ` 16 | }) 17 | export class PageViewsByBrowserWidget { 18 | 19 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-exercise/page-views-pie-chart.component.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component} from "@angular/core"; 4 | 5 | @Component({ 6 | selector: 'dashboard-section', 7 | template: ` 8 | 9 |
10 |

Pages Views (Pie Chart)

11 | 13 |
14 | 15 | ` 16 | }) 17 | export class PageViewsPieChartWidget { 18 | 19 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-exercise/router-config.ts: -------------------------------------------------------------------------------- 1 | import {Routes} from "@angular/router"; 2 | import {DashboardHeader} from "./dashboard-header"; 3 | import {PageViewsByBrowserWidget} from "./page-views-by-browser.component"; 4 | import {PageViewsPieChartWidget} from "./page-views-pie-chart.component"; 5 | import {ImpressionsByCountryWidget} from "./impresssions-by-country.component"; 6 | 7 | 8 | export const routeConfig:Routes = [ 9 | 10 | { 11 | path: '', 12 | pathMatch:'full', 13 | redirectTo: '/home' 14 | }, 15 | { 16 | path: 'home', 17 | component: DashboardHeader 18 | }, 19 | { 20 | path: 'section1', 21 | component: PageViewsByBrowserWidget, 22 | outlet: 'section1' 23 | }, 24 | { 25 | path: 'section2', 26 | component: PageViewsPieChartWidget, 27 | outlet: 'section2' 28 | }, 29 | { 30 | path: 'section3', 31 | component: ImpressionsByCountryWidget, 32 | outlet: 'section3' 33 | } 34 | 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-exercise/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/all-lessons.component.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {LessonsList} from "./lessons-list.component"; 4 | import {lessonsData} from "./lessonsData"; 5 | 6 | 7 | @Component({ 8 | selector: 'all-lessons', 9 | template: ` 10 | 11 |

All Lessons

12 | 13 | 14 | 15 | ` 16 | }) 17 | export class AllLessons { 18 | 19 | lessons = lessonsData.lessons; 20 | 21 | 22 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, NgModule} from "@angular/core"; 3 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 4 | import {BrowserModule} from "@angular/platform-browser"; 5 | import {RouterModule} from "@angular/router"; 6 | import {routeConfig} from "./router-config"; 7 | import {SharedModule} from "./shared.module"; 8 | import {Home} from "./home.component"; 9 | import {Playlist} from "./playlist.component"; 10 | import {AllLessons} from "./all-lessons.component"; 11 | 12 | 13 | @Component({ 14 | selector:'app', 15 | template: ` 16 | 17 | 39 | 40 |
41 | 42 |
43 | 44 |
45 |
46 | 47 |
48 |
49 | 50 |
51 |
52 | 53 |
54 | 55 |
56 | 57 | ` 58 | }) 59 | export class App { 60 | 61 | 62 | 63 | } 64 | 65 | 66 | 67 | @NgModule({ 68 | declarations: [App, Home, Playlist, AllLessons], 69 | imports: [ 70 | BrowserModule, 71 | RouterModule.forRoot(routeConfig), 72 | SharedModule 73 | ], 74 | bootstrap: [App] 75 | 76 | }) 77 | export class AppModule { 78 | 79 | } 80 | 81 | platformBrowserDynamic().bootstrapModule(AppModule); 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/chat.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component} from "@angular/core"; 4 | 5 | @Component({ 6 | selector:'chat', 7 | template: ` 8 | 9 |
10 | 11 | 12 | 13 |
14 | 15 | ` 16 | }) 17 | export class Chat { 18 | 19 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/course-detail-activate.guard.ts: -------------------------------------------------------------------------------- 1 | import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from "@angular/router"; 2 | import {Observable, Subject} from "rxjs/Rx"; 3 | import {coursesData} from "./coursesData"; 4 | 5 | 6 | export class CanCourseDetailActivate implements CanActivate { 7 | 8 | 9 | canActivate(route:ActivatedRouteSnapshot, 10 | state:RouterStateSnapshot):Observable|boolean { 11 | 12 | 13 | const subject = new Subject(); 14 | 15 | setTimeout(() => { 16 | 17 | const index = route.params['id'] - 1; 18 | 19 | const course = coursesData.courses[index]; 20 | 21 | subject.next(course ? !course.pro : true); 22 | subject.complete(); 23 | 24 | }); 25 | 26 | return subject; 27 | 28 | } 29 | 30 | 31 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/course-detail-deactivate.guard.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import {CanDeactivate, RouterStateSnapshot, ActivatedRouteSnapshot} from "@angular/router"; 5 | import {CourseDetail} from "./course-detail.component"; 6 | import {Observable} from "rxjs/Rx"; 7 | 8 | export class CanCourseDetailDeactivate 9 | implements CanDeactivate { 10 | 11 | 12 | canDeactivate(component:CourseDetail, 13 | route:ActivatedRouteSnapshot, 14 | state:RouterStateSnapshot):Observable|boolean { 15 | 16 | 17 | if (!component.dirty) { 18 | return true; 19 | } 20 | 21 | return confirm("Unsaved changes exist, do you want to exit ?"); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/course-detail.component.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component, OnDestroy} from "@angular/core"; 4 | import {lessonsData} from "./lessonsData"; 5 | import {LessonsList} from "./lessons-list.component"; 6 | import {Router, ActivatedRoute} from "@angular/router"; 7 | import {Subscription} from "rxjs/Rx"; 8 | 9 | 10 | @Component({ 11 | selector:'course-detail', 12 | template: ` 13 | 14 |
15 |

{{description}} Course id = {{courseId}}

16 | 21 | 22 |
23 | 24 | 25 | ` 26 | }) 27 | export class CourseDetail implements OnDestroy { 28 | 29 | 30 | courseId: number; 31 | 32 | lessons = lessonsData.lessons; 33 | description:string; 34 | 35 | paramsSub: Subscription; 36 | queryParamsSub: Subscription; 37 | 38 | dirty = false; 39 | 40 | 41 | 42 | constructor(route:ActivatedRoute) { 43 | 44 | this.paramsSub = route.params.subscribe( 45 | params =>{ 46 | this.courseId = parseInt(params['id']); 47 | this.dirty = false; 48 | } 49 | ); 50 | 51 | this.queryParamsSub = route.queryParams.subscribe( 52 | params => { 53 | this.description = params['description']; 54 | } 55 | ); 56 | 57 | console.log('observers count', 58 | route.queryParams['observers'].length); 59 | 60 | } 61 | 62 | previous() { 63 | return this.courseId - 1; 64 | } 65 | 66 | next() { 67 | return this.courseId + 1; 68 | } 69 | 70 | 71 | ngOnDestroy() { 72 | this.paramsSub.unsubscribe(); 73 | this.queryParamsSub.unsubscribe(); 74 | } 75 | } 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/courses-list.component.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, Input} from "@angular/core"; 3 | import {Router, ActivatedRoute} from "@angular/router"; 4 | 5 | 6 | @Component({ 7 | selector:'courses-list', 8 | template: ` 9 | 10 | 12 | 16 | 19 | 22 | 23 |
13 | 15 | 17 | {{course.description}} 18 | 20 | 21 |
24 | 25 | 26 | 27 | ` 28 | }) 29 | export class CoursesList { 30 | 31 | 32 | @Input() 33 | courses = []; 34 | 35 | 36 | constructor(private router:Router, private route: ActivatedRoute) { 37 | 38 | } 39 | 40 | 41 | openCourse(course, $event) { 42 | 43 | this.router.navigateByUrl(`/courses/${course.id}`); 44 | $event.stopPropagation(); 45 | 46 | } 47 | 48 | showCoursePlayList(course) { 49 | 50 | this.router.navigateByUrl( 51 | `/courses(playlist:playlist;description=${course.description})` 52 | ); 53 | 54 | } 55 | 56 | 57 | 58 | } 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/courses-router-config.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import {Playlist} from "./playlist.component"; 5 | 6 | 7 | export const coursesRouterConfig = [ 8 | { 9 | path: 'courses', 10 | loadChildren: '/src/router-introduction/courses.module' 11 | }, 12 | { 13 | path: 'playlist', 14 | component: Playlist, 15 | outlet: 'playlist' 16 | } 17 | ]; -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/courses.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {coursesData} from "./coursesData"; 3 | import {CoursesList} from "./courses-list.component"; 4 | 5 | 6 | 7 | @Component({ 8 | selector: 'courses', 9 | template: ` 10 | 11 |

Courses

12 | 13 | 14 | 15 | ` 16 | }) 17 | export class Courses { 18 | 19 | courses = coursesData.courses; 20 | 21 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/courses.module.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {NgModule} from "@angular/core"; 4 | import {CoursesList} from "./courses-list.component"; 5 | import {CommonModule} from "@angular/common"; 6 | import {Courses} from "./courses.component"; 7 | import {CourseDetail} from "./course-detail.component"; 8 | import {CanCourseDetailDeactivate} from "./course-detail-deactivate.guard"; 9 | import {CanCourseDetailActivate} from "./course-detail-activate.guard"; 10 | import {RouterModule} from "@angular/router"; 11 | import {SharedModule} from "./shared.module"; 12 | 13 | 14 | const routerConfig = [ 15 | { 16 | path: '', 17 | component: Courses 18 | }, 19 | { 20 | path: 'legacy-list', 21 | redirectTo: '/lessons', 22 | pathMatch: 'full' 23 | }, 24 | { 25 | path: ':id', 26 | canActivate: [CanCourseDetailActivate], 27 | canDeactivate: [CanCourseDetailDeactivate], 28 | component: CourseDetail 29 | } 30 | ]; 31 | 32 | 33 | @NgModule({ 34 | imports: [CommonModule, 35 | RouterModule.forChild(routerConfig), SharedModule], 36 | declarations: [Courses, CoursesList, CourseDetail], 37 | exports: [CoursesList], 38 | providers: [CanCourseDetailDeactivate, CanCourseDetailActivate] 39 | }) 40 | export default class CoursesModule { 41 | 42 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/coursesData.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export const coursesData = { 4 | 5 | courses: [ 6 | { 7 | id:1, 8 | description: "Angular For Beginners", 9 | pro:false 10 | }, 11 | { 12 | id:2, 13 | description: "Angular HTTP", 14 | pro:false 15 | }, 16 | { 17 | id:3, 18 | description: "Angular Forms", 19 | pro:false 20 | }, 21 | { 22 | id:4, 23 | description: "Angular Router", 24 | pro:true 25 | }, 26 | { 27 | id:5, 28 | description: "Angular Universal", 29 | pro:false 30 | }, 31 | { 32 | id:6, 33 | description: "Progressive Web Apps", 34 | pro:false 35 | } 36 | ] 37 | 38 | }; -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/home.component.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {LessonsList} from "./lessons-list.component"; 4 | import {lessonsData} from "./lessonsData"; 5 | 6 | 7 | @Component({ 8 | selector: 'home', 9 | template: ` 10 | 11 | 13 | 14 |
15 |

Latest Lessons

16 | 17 |
18 | 19 | 20 | ` 21 | }) 22 | export class Home { 23 | 24 | lessons = lessonsData.lessons; 25 | 26 | 27 | 28 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/lesson.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export class Lesson { 4 | 5 | id:string; 6 | url: string; 7 | description:string; 8 | duration: string; 9 | tags:string; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/lessons-list.component.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, Input} from "@angular/core"; 3 | 4 | 5 | @Component({ 6 | selector:'lessons-list', 7 | template: ` 8 | 9 | 10 | 14 | 17 | 20 | 21 |
11 | 13 | 15 | {{lesson.description}} 16 | 18 | 19 |
22 | 23 | ` 24 | }) 25 | export class LessonsList { 26 | 27 | 28 | @Input() 29 | lessons = []; 30 | 31 | 32 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/lessonsData.ts: -------------------------------------------------------------------------------- 1 | export const lessonsData = { 2 | lessons: [ 3 | { 4 | id: 1, 5 | url: 'angular2-hello-world-write-first-application', 6 | description:'Build Your First App - Hello World Step By Step', 7 | duration: '2:49', 8 | tags:"BEGINNER" 9 | }, 10 | { 11 | id: 2, 12 | url: 'angular2-build-your-first-component', 13 | description:'Building Your First Component', 14 | duration: '2:07', 15 | tags:"BEGINNER" 16 | }, 17 | { 18 | id: 3, 19 | url: 'angular2-passing-data-to-component-using-input', 20 | description:'Component @Input - How To Pass Input Data To a Component', 21 | duration: '2:33', 22 | tags:"BEGINNER" 23 | }, 24 | { 25 | id: 4, 26 | url: 'angular2-component-events', 27 | description:'Component Events - Using @Output to create custom events', 28 | duration: '4:44', 29 | tags:"BEGINNER" 30 | }, 31 | { 32 | id: 5, 33 | url: 'angular2-component-templates-internal-vs-external', 34 | description:'Component Templates - Inline Vs External', 35 | duration: '2:55', 36 | tags:"BEGINNER" 37 | }, 38 | { 39 | id: 6, 40 | url: 'angular2-components-styling-component-isolation', 41 | description:'Styling Components - Learn About Component Style Isolation', 42 | duration: '3:27', 43 | tags:"BEGINNER" 44 | }, 45 | { 46 | id: 7, 47 | url: 'angular2-components-component-interaction', 48 | description:'Component Interaction - Extended Components Example', 49 | duration: '5:27', 50 | tags:"BEGINNER" 51 | }, 52 | { 53 | id: 8, 54 | url: 'angular2-components-exercise', 55 | description:'Components Exercise !', 56 | duration: '1:26', 57 | tags:"BEGINNER" 58 | }, 59 | { 60 | id: 9, 61 | url: 'angular2-components-exercise-solution', 62 | description:'Components Exercise Solution Inside', 63 | duration: '2:08', 64 | tags:"BEGINNER" 65 | } 66 | ]}; -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/playlist.component.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {Component} from "@angular/core"; 4 | import {lessonsData} from "./lessonsData"; 5 | import {LessonsList} from "./lessons-list.component"; 6 | import {ActivatedRoute} from "@angular/router"; 7 | 8 | 9 | @Component({ 10 | selector: 'playlist', 11 | template: ` 12 | 13 |
14 |

{{description}}

15 | 16 |
17 | 18 | ` 19 | }) 20 | export class Playlist { 21 | 22 | description:string; 23 | 24 | lessons = lessonsData.lessons; 25 | 26 | 27 | constructor(route: ActivatedRoute) { 28 | 29 | route.params.subscribe( 30 | params => this.description = params['description'] 31 | ); 32 | 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/router-config.ts: -------------------------------------------------------------------------------- 1 | import {AllLessons} from "./all-lessons.component"; 2 | import {Home} from "./home.component"; 3 | import {Route} from "@angular/router"; 4 | import {coursesRouterConfig} from "./courses-router-config"; 5 | 6 | 7 | const indexRoute:Route = { 8 | path: "", 9 | component: Home 10 | }; 11 | 12 | const fallbackRoute:Route = { 13 | path: '**', 14 | component: Home 15 | }; 16 | 17 | export const routeConfig = [ 18 | { 19 | path: 'home', 20 | component: Home 21 | }, 22 | ...coursesRouterConfig, 23 | { 24 | path: 'lessons', 25 | component: AllLessons 26 | }, 27 | fallbackRoute, 28 | indexRoute 29 | ]; 30 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/router.css: -------------------------------------------------------------------------------- 1 | 2 | .l-header { 3 | height: 58px; 4 | } 5 | 6 | .top-menu { 7 | margin-left: 50px; 8 | } 9 | 10 | .top-menu li { 11 | box-shadow: none !important; 12 | } 13 | 14 | .l-sample-app { 15 | text-align: center; 16 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/shared.module.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import {NgModule} from "@angular/core"; 4 | import {LessonsList} from "./lessons-list.component"; 5 | import {CommonModule} from "@angular/common"; 6 | 7 | 8 | @NgModule({ 9 | declarations: [LessonsList], 10 | exports: [LessonsList], 11 | imports: [CommonModule] 12 | 13 | }) 14 | export class SharedModule { 15 | 16 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/router-introduction/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-http/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {LessonsList} from "./lessons-list.component"; 8 | import {HttpModule} from "@angular/http"; 9 | import "rxjs/Rx"; 10 | import {LessonsService} from "./lessons.service"; 11 | import {initObservable} from "./init-observable"; 12 | import {Observable} from "rxjs/Observable"; 13 | import {Lesson} from "./lesson"; 14 | 15 | @Component({ 16 | selector:'app', 17 | template: ` 18 | 19 |
20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | ` 30 | }) 31 | export class App { 32 | 33 | lessons$: Observable; 34 | 35 | constructor(private lessonsService: LessonsService) { 36 | 37 | initObservable(); 38 | 39 | this.lessons$ = lessonsService.loadLessons(); 40 | } 41 | 42 | createLesson(description) { 43 | this.lessonsService.createLesson(description); 44 | } 45 | 46 | chain() { 47 | 48 | const lesson = "Lesson 1"; 49 | 50 | const lesson2 = "Lesson2"; 51 | 52 | const chain$ = this.lessonsService.createLesson(lesson) 53 | .switchMap(results => { 54 | console.log('result', results); 55 | return this.lessonsService.createLesson(lesson2) 56 | }) 57 | .switchMap((results2) => { 58 | console.log(results2); 59 | return this.lessonsService.loadLessons(); 60 | }) 61 | .cache(); 62 | 63 | 64 | this.lessons$ = chain$; 65 | 66 | chain$.subscribe(); 67 | 68 | 69 | } 70 | 71 | } 72 | 73 | 74 | 75 | @NgModule({ 76 | declarations: [App, LessonsList], 77 | imports: [BrowserModule, HttpModule], 78 | bootstrap: [App], 79 | providers: [LessonsService] 80 | }) 81 | export class AppModule { 82 | 83 | } 84 | 85 | platformBrowserDynamic().bootstrapModule(AppModule); 86 | 87 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-http/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Really Understanding Angular - The Fundamentals
48 | 49 |
50 | 51 |
52 | 53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-http/init-observable.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Observable} from "rxjs/Observable"; 3 | declare function fetch(url:string); 4 | 5 | 6 | 7 | 8 | export function initObservable() { 9 | 10 | const click$ = Observable.fromEvent(document,'click'); 11 | 12 | const mouse$ = Observable.fromEvent(document,'mousemove') 13 | .filter((move:MouseEvent) => move.clientY >=200); 14 | 15 | 16 | const combined$ = Observable.combineLatest(mouse$, click$); 17 | /* 18 | combined$.subscribe( 19 | combined => console.log(combined[0]) 20 | ); 21 | 22 | */ 23 | } 24 | 25 | /* 26 | * // mouse clicks 27 | * 28 | * |------------------------x---------------------x-------.... 29 | * 30 | * 31 | * // mouse move 32 | * 33 | * |--(x,y)--(x,y)--(x,y)--(x,y)--(x,y)-(x,y)-(x,y)-(x,y)-(x,y).... 34 | * 35 | * 36 | * // mouse move bellow 200 37 | * 38 | * |----------------(x,y)---------(x,y)----... 39 | * 40 | * 41 | * // combined 42 | * 43 | * |-------------------------(x,y)---..... 44 | * 45 | * 46 | * */ 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-http/lesson.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export class Lesson { 4 | 5 | id:string; 6 | url: string; 7 | description:string; 8 | duration: string; 9 | tags:string; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-http/lessons-list.component.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, Input} from "@angular/core"; 3 | import {LessonsService} from "./lessons.service"; 4 | 5 | 6 | @Component({ 7 | selector:'lessons-list', 8 | template: ` 9 | 10 | 11 | 15 | 18 | 21 | 22 |
12 | 14 | 16 | {{lesson.description}} 17 | 19 | 20 |
23 | 24 | ` 25 | }) 26 | export class LessonsList { 27 | 28 | 29 | @Input() 30 | lessons = []; 31 | 32 | 33 | constructor(private lessonsService: LessonsService) { 34 | 35 | } 36 | 37 | 38 | 39 | 40 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-http/lessons.service.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Injectable} from "@angular/core"; 3 | import {Http, URLSearchParams} from "@angular/http"; 4 | import {xhrHeaders} from "./xhr-headers"; 5 | import {Lesson} from "./lesson"; 6 | import {Observable} from "rxjs/Observable"; 7 | 8 | 9 | @Injectable() 10 | export class LessonsService { 11 | 12 | 13 | constructor(private http: Http) { 14 | 15 | } 16 | 17 | loadLessons(search = ""): Observable { 18 | 19 | console.log(`searching for ${search}`); 20 | 21 | let params: URLSearchParams = new URLSearchParams(); 22 | params.set('search', search); 23 | 24 | return this.http.get('/lessons', {search:params}).map(res => res.json()); 25 | } 26 | 27 | 28 | loadFlakyLessons() { 29 | return this.http.get('/flakylessons').map(res => res.json()); 30 | } 31 | 32 | loadDelayedLessons(search = "") { 33 | 34 | console.log(`searching for ${search}`); 35 | 36 | let params: URLSearchParams = new URLSearchParams(); 37 | params.set('search', search); 38 | 39 | return this.http.get('/delayedlessons', {search:params}).map(res => res.json()); 40 | } 41 | 42 | createLesson(description) { 43 | 44 | const network$ = this.http.post('/lessons', 45 | JSON.stringify({description}), 46 | xhrHeaders()) 47 | .cache(); 48 | 49 | network$.subscribe( 50 | () => console.log('HTTP post successful !'), 51 | err => console.error(err), 52 | () => console.log('monitoring completed ...') 53 | 54 | ); 55 | 56 | return network$; 57 | 58 | } 59 | 60 | delete(lessonId) { 61 | return this.http.delete(`/lessons/${lessonId}`, xhrHeaders()); 62 | } 63 | 64 | 65 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-http/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-http/xhr-headers.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Headers} from "@angular/http"; 3 | 4 | export function xhrHeaders() { 5 | const headers = new Headers(); 6 | headers.append('Content-Type', 'application/json; charset=utf-8'); 7 | headers.append('X-Requested-With','XMLHttpRequest'); 8 | return {headers}; 9 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-intro/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component} from "@angular/core"; 3 | import {NgModule} from "@angular/core"; 4 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 5 | import {BrowserModule} from "@angular/platform-browser"; 6 | 7 | import {LessonsList} from "./lessons-list.component"; 8 | import {HttpModule} from "@angular/http"; 9 | import "rxjs/Rx"; 10 | import {LessonsService} from "./lessons.service"; 11 | 12 | 13 | @Component({ 14 | selector:'app', 15 | template: ` 16 | 17 | 19 | 20 | 21 | 22 | ` 23 | }) 24 | export class App { 25 | 26 | constructor(private lessonsService: LessonsService) { 27 | 28 | } 29 | 30 | } 31 | 32 | @NgModule({ 33 | declarations: [App, LessonsList], 34 | imports: [BrowserModule, HttpModule], 35 | bootstrap: [App], 36 | providers: [LessonsService] 37 | }) 38 | export class AppModule { 39 | 40 | } 41 | 42 | 43 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-intro/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Really Understanding Angular - The Fundamentals 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 |
45 | 46 | 47 |
Really Understanding Angular - The Fundamentals
48 | 49 |
50 | 51 |
52 | 53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-intro/lessons-list.component.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Component, Input} from "@angular/core"; 3 | import {LessonsService} from "./lessons.service"; 4 | 5 | 6 | @Component({ 7 | selector:'lessons-list', 8 | template: ` 9 | 10 | 11 | 15 | 18 | 21 | 22 |
12 | 14 | 16 | {{lesson.description}} 17 | 19 | 20 |
23 | 24 | ` 25 | }) 26 | export class LessonsList { 27 | 28 | 29 | @Input() 30 | lessons = []; 31 | 32 | 33 | constructor(private lessonsService: LessonsService) { 34 | 35 | } 36 | 37 | 38 | 39 | 40 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-intro/lessons.service.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Injectable} from "@angular/core"; 3 | import {Http} from "@angular/http"; 4 | import {xhrHeaders} from "./xhr-headers"; 5 | 6 | 7 | @Injectable() 8 | export class LessonsService { 9 | 10 | lessons = []; 11 | 12 | constructor(private http: Http) { 13 | this.loadLessons(); 14 | } 15 | 16 | loadLessons() { 17 | this.http.get('/lessons') 18 | .map(res => res.json()) 19 | .subscribe( 20 | lessons => this.lessons = lessons, 21 | err => console.error(err) 22 | ); 23 | } 24 | 25 | createLesson(description) { 26 | console.log("creating lesson ..."); 27 | const lesson = {description}; 28 | this.lessons.push(lesson); 29 | this.http.post('/lessons', JSON.stringify(lesson), xhrHeaders()) 30 | .subscribe( 31 | () => {}, 32 | err => console.error(err) 33 | ); 34 | } 35 | 36 | delete(lessonId) { 37 | console.log("deleting lesson ..."); 38 | const index = this.lessons.findIndex( 39 | lesson => lesson.id === lessonId 40 | ); 41 | this.lessons.splice(index, 1); 42 | this.http.delete(`/lessons/${lessonId}`, xhrHeaders()) 43 | .subscribe( 44 | () => {}, 45 | err => console.error(err) 46 | ); 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-intro/lessons.ts: -------------------------------------------------------------------------------- 1 | export const lessonsData = [ 2 | { 3 | id: 1, 4 | url: 'angular2-hello-world-write-first-application', 5 | description:'Build Your First App - Hello World Step By Step', 6 | duration: '2:49', 7 | tags:"BEGINNER" 8 | }, 9 | { 10 | id: 2, 11 | url: 'angular2-build-your-first-component', 12 | description:'Building Your First Component', 13 | duration: '2:07', 14 | tags:"BEGINNER" 15 | }, 16 | { 17 | id: 3, 18 | url: 'angular2-passing-data-to-component-using-input', 19 | description:'Component @Input - How To Pass Input Data To a Component', 20 | duration: '2:33', 21 | tags:"BEGINNER" 22 | }, 23 | { 24 | id: 4, 25 | url: 'angular2-component-events', 26 | description:'Component Events - Using @Output to create custom events', 27 | duration: '4:44', 28 | tags:"BEGINNER" 29 | }, 30 | { 31 | id: 5, 32 | url: 'angular2-component-templates-internal-vs-external', 33 | description:'Component Templates - Inline Vs External', 34 | duration: '2:55', 35 | tags:"BEGINNER" 36 | }, 37 | { 38 | id: 6, 39 | url: 'angular2-components-styling-component-isolation', 40 | description:'Styling Components - Learn About Component Style Isolation', 41 | duration: '3:27', 42 | tags:"BEGINNER" 43 | }, 44 | { 45 | id: 7, 46 | url: 'angular2-components-component-interaction', 47 | description:'Component Interaction - Extended Components Example', 48 | duration: '5:27', 49 | tags:"BEGINNER" 50 | }, 51 | { 52 | id: 8, 53 | url: 'angular2-components-exercise', 54 | description:'Components Exercise !', 55 | duration: '1:26', 56 | tags:"BEGINNER" 57 | }, 58 | { 59 | id: 9, 60 | url: 'angular2-components-exercise-solution', 61 | description:'Components Exercise Solution Inside', 62 | duration: '2:08', 63 | tags:"BEGINNER" 64 | } 65 | ]; -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-intro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/services-intro/xhr-headers.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Headers} from "@angular/http"; 3 | 4 | export function xhrHeaders() { 5 | const headers = new Headers(); 6 | headers.append('Content-Type', 'application/json; charset=utf-8'); 7 | headers.append('X-Requested-With','XMLHttpRequest'); 8 | return {headers}; 9 | } -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/typescript-introduction/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/src/typescript-introduction/typescript-introduction.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | var hello = "Hello World !"; 4 | 5 | if (hello) { 6 | console.log(hello); 7 | } 8 | 9 | 10 | const message = `message: ${hello}`; 11 | 12 | console.log(message); 13 | 14 | 15 | 16 | function printMessage(message:string, 17 | callback: Function) { 18 | console.log(message); 19 | callback(); 20 | } 21 | 22 | 23 | printMessage(message, () => { 24 | console.log('callback was called ...'); 25 | }); 26 | 27 | 28 | -------------------------------------------------------------------------------- /01-getting-started-with-angular2/system.config.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 3 | //map tells the System loader where to look for things 4 | var map = { 5 | 6 | '@angular': '/node_modules/@angular', // sufficient if we didn't pin the version 7 | '@angular/router': '/node_modules/@angular/router' , 8 | '@angular/forms': '/node_modules/@angular/forms', 9 | 'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest 10 | 'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6', 11 | 'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js', 12 | 'typescript': 'https://npmcdn.com/typescript@1.9.0-dev.20160409/lib/typescript.js', 13 | }; 14 | 15 | //packages tells the System loader how to load when no filename and/or no extension 16 | var packages = { 17 | 'rxjs': {defaultExtension: 'js'}, 18 | 'angular2-in-memory-web-api': {main: 'index.js', defaultExtension: 'js'}, 19 | }; 20 | 21 | var ngPackageNames = [ 22 | 'common', 23 | 'compiler', 24 | 'core', 25 | 'http', 26 | 'platform-browser', 27 | 'platform-browser-dynamic', 28 | 'router-deprecated', 29 | 'upgrade', 30 | 'forms', 31 | 'router' 32 | ]; 33 | 34 | // Add map entries for each angular package 35 | ngPackageNames.forEach(function (pkgName) { 36 | map['@angular/' + pkgName] = '/node_modules/@angular/' + pkgName; 37 | }); 38 | 39 | // Add package entries for angular packages 40 | ngPackageNames.forEach(function (pkgName) { 41 | 42 | // Bundled (~40 requests): 43 | packages['@angular/' + pkgName] = {main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js'}; 44 | 45 | // Individual files (~300 requests): 46 | //packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; 47 | }); 48 | 49 | var config = { 50 | // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER 51 | transpiler: 'ts', 52 | typescriptOptions: { 53 | tsconfig: true 54 | }, 55 | meta: { 56 | 'typescript': { 57 | "exports": "ts" 58 | } 59 | }, 60 | map: map, 61 | packages: packages 62 | }; 63 | 64 | document.SYSTEMJS_CONFIG = config; 65 | 66 | })(this); 67 | 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular University Lessons Code 2 | Contains the code for several of the [Angular University](https://angular-university.io) courses. 3 | 4 | This course repository is updated to Angular 5, there is a Yarn lock file available. 5 | 6 | 7 | [Angular for Beginners Course](https://angular-university.io/course/getting-started-with-angular2) 8 | 9 | ![Angular for Beginners course](https://angular-academy.s3.amazonaws.com/thumbnails/angular2-for-beginners-small-v2.png) 10 | 11 | 12 | # Which Course are You Looking For ? 13 | 14 | If you are looking for the code of the following courses, see further the installation instructions on this page: 15 | 16 | - [Angular For Beginners](https://angular-university.io/course/getting-started-with-angular2) 17 | - [Angular Services and HTTP](https://angular-university.io/course/angular2-http) 18 | - [Angular Router](https://angular-university.io/course/angular2-routing) 19 | - [Angular Forms](https://angular-university.io/course/angular2-forms) 20 | 21 | # Angular and Firebase - Build a Web Application Course 22 | 23 | If you are looking for the Angular and Firebase - Build a Web Application Course code, the repo with the full code can be found here: 24 | 25 | [Angular and Firebase - Build a Web Application](https://angular-university.io/course/build-an-application-with-angular2) 26 | 27 | [Github Repo For this course](https://github.com/angular-university/angular-firebase-app) 28 | 29 | ![Angular firebase course](https://angular-academy.s3.amazonaws.com/thumbnails/angular_app-firebase-small-v2.png) 30 | 31 | 32 | # Complete Typescript 2 Course - Build A REST API 33 | 34 | If you are looking for the Complete Typescript 2 Course - Build a REST API, the repo with the full code can be found here: 35 | 36 | [Complete Typescript 2 Course - Build A REST API](https://angular-university.io/course/typescript-2-tutorial) 37 | 38 | [Github Repo for this course](https://github.com/angular-university/complete-typescript-course) 39 | 40 | ![Complete Typescript Course](https://angular-academy.s3.amazonaws.com/thumbnails/typescript-2-small.png) 41 | 42 | 43 | # Angular Ngrx Reactive Extensions Architecture Course 44 | 45 | If you are looking for the Angular Ngrx Reactive Extensions Architecture Course code, the repo with the full code can be found here: 46 | 47 | [Angular Ngrx Reactive Extensions Architecture Course](https://angular-university.io/course/angular2-ngrx) 48 | 49 | [Github repo for this course](https://github.com/angular-university/ngrx-course) 50 | 51 | ![Angular Ngrx Course](https://angular-academy.s3.amazonaws.com/thumbnails/ngrx-angular.png) 52 | 53 | 54 | # RxJs And Reactive Patterns Angular Architecture Course 55 | 56 | If you are looking for the RxJs And Reactive Patterns Angular Architecture Course code, the repo with the full code can be found here: 57 | 58 | [RxJs and Reactive Patterns Angular Architecture Course](https://angular-university.io/course/reactive-angular-architecture-course) 59 | 60 | [Github repo for this course](https://github.com/angular-university/reactive-patterns-course) 61 | 62 | ![RxJs and Reactive Patterns Angular Architecture Course](https://s3-us-west-1.amazonaws.com/angular-academy/blog/images/rxjs-reactive-patterns-small.png) 63 | 64 | 65 | 66 | # Installation pre-requisites 67 | 68 | This project has minimal dependencies, you only need node and npm installed on your machine. These are some tutorials to install node in different operating systems. 69 | 70 | *Make sure to install the latest version of Node 6* 71 | 72 | - [Install Node and NPM on Windows](https://www.youtube.com/watch?v=8ODS6RM6x7g) 73 | - [Install Node and NPM on Linux](https://www.youtube.com/watch?v=yUdHk-Dk_BY) 74 | - [Install Node and NPM on Mac](https://www.youtube.com/watch?v=Imj8PgG3bZU) 75 | 76 | 77 | # Installation Instructions 78 | 79 | First clone or download as a Zip file using the green "Clone Or Download" button on the top right of the document. 80 | 81 | Then change directory to the folder 01-getting-started-with-angular2, where you will find a small node project with a `package.json`. 82 | 83 | On the command line run the following: 84 | 85 | npm install 86 | 87 | If you prefer the Yarn package manager, you can also run: 88 | 89 | yarn 90 | 91 | Although npm install would also work, its recommended to use Yarn to install the course dependencies. Yarn has the big advantage that if you use it you will be 92 | installing the exact same dependencies than I installed in my machine, so you wont run into issues caused by semantic versioning updates. 93 | 94 | This should take a couple of minutes. If there are issues, please post the complete error message in the Questions section of the course. 95 | 96 | # Starting the development server 97 | 98 | To start the server, run the following command: 99 | 100 | npm start 101 | 102 | If you now go to [http://localhost:8080](http://localhost:8080), there will be a running application at this url. 103 | 104 | # Making changes 105 | 106 | If you edit a Typescript file and refresh the browser, the changes will be applied. 107 | 108 | 109 | ## Brought to you by the Angular University 110 | 111 | Have a look at our course pipeline at [angular-university.io](https://angular-university.io/). 112 | 113 | 114 | -------------------------------------------------------------------------------- /theme/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "theme", 3 | "version": "1.0.0", 4 | "description": "Angular Academy Lessons Theme", 5 | "scripts": { 6 | "build": "node-sass -o dist styles/angular-academy-lessons-theme.scss", 7 | "watch": "nodemon -V -w styles --ext \".scss\" --exec \"npm run build\"" 8 | }, 9 | "devDependencies": { 10 | "node-sass": "^3.5.3" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /theme/styles/angular-academy-lessons-theme.scss: -------------------------------------------------------------------------------- 1 | 2 | @import "vendors/normalize"; 3 | @import "project/fonts"; 4 | @import "project/colors"; 5 | @import "project/defaults"; 6 | @import "project/layout"; 7 | @import "project/centering"; 8 | @import "project/card"; 9 | @import "project/input"; 10 | @import "project/tabs"; 11 | @import "project/getting_started_lessons"; 12 | 13 | 14 | -------------------------------------------------------------------------------- /theme/styles/project/_card.scss: -------------------------------------------------------------------------------- 1 | 2 | $normal-card-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); 3 | 4 | .card { 5 | border-radius: 4px; 6 | box-shadow: $normal-card-shadow; 7 | &.hoverable:hover { 8 | box-shadow: 0 1px 16px 0 rgba(0, 0, 0, .2), 0 2px 8px 0 rgba(0, 0, 0, .14), 0 4px 8px -1px rgba(0, 0, 0, .12) 9 | } 10 | } 11 | 12 | .card.card-strong { 13 | box-shadow: 0 1px 16px 0 rgba(0, 0, 0, .2), 0 2px 8px 0 rgba(0, 0, 0, .14), 0 4px 8px -1px rgba(0, 0, 0, .12); 14 | &.hoverable:hover { 15 | box-shadow: 0 2px 32px 0 rgba(0, 0, 0, .2), 0 4px 16px 0 rgba(0, 0, 0, .14), 0 8px 16px -2px rgba(0, 0, 0, .12) 16 | } 17 | } 18 | 19 | .card 20 | 21 | 22 | .card-header { 23 | background: $primary; 24 | color: white; 25 | border-top-left-radius: 4px; 26 | border-top-right-radius: 4px; 27 | text-align: left; 28 | height: 48px; 29 | box-sizing: border-box; 30 | line-height: 48px; 31 | padding: 0 12px; 32 | 33 | } 34 | 35 | .card-body { 36 | padding:24px 12px; 37 | } 38 | -------------------------------------------------------------------------------- /theme/styles/project/_centering.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .v-center-parent { 4 | position: relative; 5 | } 6 | 7 | .v-center { 8 | position: absolute; 9 | top: 50%; 10 | transform: translateY(-50%); 11 | } 12 | 13 | .h-center-parent { 14 | position: relative; 15 | } 16 | 17 | .h-center { 18 | position: absolute; 19 | left: 50%; 20 | transform: translateX(-50%); 21 | } 22 | 23 | .v-h-center-parent { 24 | position: relative; 25 | } 26 | 27 | .v-h-center { 28 | position: absolute; 29 | top: 50%; 30 | left: 50%; 31 | transform: translateX(-50%) translateY(-50%); 32 | } 33 | -------------------------------------------------------------------------------- /theme/styles/project/_colors.scss: -------------------------------------------------------------------------------- 1 | 2 | $page-background: #FAFAFA; 3 | 4 | $primary: rgb(25, 118, 210); 5 | $primary-tint-1: #3F94E9; 6 | 7 | $secondary: rgba(0, 0, 0, 0.117647); 8 | 9 | 10 | $text:rgba(26, 35, 38, 0.8); 11 | 12 | $primary-contrast: white; 13 | 14 | $error-text: #a94442; 15 | -------------------------------------------------------------------------------- /theme/styles/project/_defaults.scss: -------------------------------------------------------------------------------- 1 | 2 | $unit: 24px; 3 | 4 | body { 5 | font-family: $Roboto; 6 | font-weight: 400; 7 | font-style: normal; 8 | font-size: $h5; 9 | line-height: $unit; 10 | margin: 0; 11 | -webkit-font-smoothing: antialiased; 12 | -moz-osx-font-smoothing: grayscale; 13 | background: $page-background; 14 | color: $text; 15 | 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /theme/styles/project/_fonts.scss: -------------------------------------------------------------------------------- 1 | 2 | $Roboto: "Roboto", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; 3 | 4 | $h0: 67px; 5 | $h1: 50px; 6 | $h2: 37px; 7 | $h3: 28px; 8 | $h4: 21px; 9 | $h5: 16px; 10 | $h6: 12px; 11 | $h7: 9px; 12 | $h8: 7px; 13 | $h9: 5px; 14 | 15 | -------------------------------------------------------------------------------- /theme/styles/project/_getting_started_lessons.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .lesson-1 { 4 | min-height: 200px; 5 | padding-top: 70px; 6 | input { 7 | margin-right: 5px; 8 | } 9 | } -------------------------------------------------------------------------------- /theme/styles/project/_input.scss: -------------------------------------------------------------------------------- 1 | input { 2 | $height: 28px; 3 | cursor: text; 4 | box-sizing: border-box; 5 | background: white; 6 | outline: none; 7 | border: 1px solid #cccccc; 8 | width: 175px; 9 | height: $height; 10 | line-height: $height; 11 | padding-left: 3px; 12 | box-shadow: inset 0 1px 3px #e6e6e6; 13 | border-radius: 3px; 14 | } 15 | 16 | input:focus { 17 | border-color: #129FEA; 18 | box-shadow: 0 0 5px rgba(102, 175, 233, 0.6); 19 | } 20 | 21 | .ng-touched.ng-invalid { 22 | border: 1px solid $error-text; 23 | } -------------------------------------------------------------------------------- /theme/styles/project/_layout.scss: -------------------------------------------------------------------------------- 1 | 2 | .l-header { 3 | $height: 2*$unit; 4 | background: $primary; 5 | color: $primary-contrast; 6 | height: $height; 7 | line-height: $height; 8 | vertical-align: middle; 9 | padding-left: 0.5 * $unit; 10 | margin-bottom: 40px; 11 | 12 | img { 13 | height: 40px; 14 | } 15 | 16 | .title { 17 | font-size: $h4; 18 | margin-left: 50px; 19 | } 20 | 21 | .l-header-url { 22 | margin-left: 35px; 23 | } 24 | } 25 | 26 | .l-course-logo { 27 | height:240px; 28 | margin: 0 auto; 29 | background-color: $page-background; 30 | background-image: url(https://material.angularjs.org/latest/img/icons/angular-logo.svg); 31 | background-repeat: no-repeat; 32 | background-position-x: center; 33 | background-size: 65px; 34 | background-position-y: center; 35 | } 36 | 37 | 38 | .l-course-title { 39 | text-align: center; 40 | font-size: $h5; 41 | } 42 | 43 | .l-lesson-title { 44 | text-align: center; 45 | font-size: $h6; 46 | } 47 | 48 | .l-course-content { 49 | margin: 47px auto; 50 | max-width: 400px; 51 | box-sizing: border-box; 52 | padding: 50px; 53 | min-height: 200px; 54 | } -------------------------------------------------------------------------------- /theme/styles/project/_tabs.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .tab-container { 4 | 5 | $tab-border: 1px solid $secondary; 6 | 7 | .tab-buttons { 8 | 9 | list-style: none; 10 | text-align: left; 11 | margin-bottom: 0; 12 | padding: 7px 0 0 10px; 13 | background: $primary; 14 | border-top-left-radius: 4px; 15 | border-top-right-radius: 4px; 16 | 17 | li { 18 | display: inline-block; 19 | color: white; 20 | background: $primary-tint-1; 21 | font-size: $h6; 22 | padding: 2px 20px; 23 | cursor: pointer; 24 | border-top-left-radius: 4px; 25 | border-top-right-radius: 4px; 26 | border-top: $tab-border; 27 | border-left: $tab-border; 28 | border-right: $tab-border; 29 | margin-right: 5px; 30 | 31 | &.selected { 32 | background: white; 33 | color:$text; 34 | border-bottom: 1px solid white; 35 | } 36 | 37 | } 38 | } 39 | 40 | .tab-panel { 41 | border-left: $tab-border; 42 | border-right: $tab-border; 43 | border-bottom: $tab-border; 44 | } 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /theme/styles/vendors/_normalize.scss: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | -moz-box-sizing: content-box; 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-appearance: textfield; /* 1 */ 359 | -moz-box-sizing: content-box; 360 | -webkit-box-sizing: content-box; /* 2 */ 361 | box-sizing: content-box; 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | border: 1px solid #c0c0c0; 381 | margin: 0 2px; 382 | padding: 0.35em 0.625em 0.75em; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | border: 0; /* 1 */ 392 | padding: 0; /* 2 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-collapse: collapse; 421 | border-spacing: 0; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } --------------------------------------------------------------------------------