Update for the final version of Angular2

It lost some functionality, but it was never put to use.
This commit is contained in:
Gergely Polonkai 2016-10-27 17:52:55 +02:00
parent bfcabd7925
commit 3e02eb4abb
24 changed files with 243 additions and 360 deletions

27
app/app-routing.module.ts Normal file
View File

@ -0,0 +1,27 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { DashboardComponent } from "./dashboard.component";
import { DucksComponent } from "./ducks.component";
const routes: Routes = [
{
path: '',
redirectTo: '/dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
component: DashboardComponent,
},
{
path: 'ducks',
component: DucksComponent
}
]
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}

View File

@ -1,7 +1,10 @@
import { Component } from "@angular/core";
@Component({
selector: "duckbook-front",
templateUrl: "/app/app.component.html"
moduleId: module.id,
selector: "duckbook-front-app",
templateUrl: "app.component.html"
})
export class AppComponent {}
export class AppComponent {
title = "Rubber Duck Booking Tool";
}

View File

@ -1,37 +1,32 @@
import "./rxjs-extensions";
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { HttpModule } from "@angular/http";
import { InMemoryWebApiModule } from "angular2-in-memory-web-api";
import { AppRoutingModule } from "./app-routing.module";
import { InMemoryWebApiModule } from "angular-in-memory-web-api";
import { InMemoryDataService } from "./in-memory-data.service";
import { routing } from "./app.routing";
import { AppComponent } from "./app.component";
import { DucksComponent } from "./ducks.component";
import { DuckDetailComponent } from "./duck-detail.component";
import { DashboardComponent } from "./dashboard.component";
import { DuckSearchComponent } from "./duck-search.component";
import { DucksComponent } from "./ducks.component";
import { DuckService } from "./duck.service";
@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
InMemoryWebApiModule.forRoot(InMemoryDataService),
routing
AppRoutingModule
],
declarations: [
AppComponent,
DucksComponent,
DashboardComponent,
DuckDetailComponent,
DuckSearchComponent,
DashboardComponent
DucksComponent
],
providers: [ DuckService ],
bootstrap: [ AppComponent ]

View File

@ -1,28 +0,0 @@
import { ModuleWithProviders } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import { DucksComponent } from "./ducks.component";
import { DuckDetailComponent } from "./duck-detail.component";
import { DashboardComponent } from "./dashboard.component";
const appRoutes: Routes = [
{
path: "",
redirectTo: "/dashboard",
pathMatch: "full"
},
{
path: "dashboard",
component: DashboardComponent
},
{
path: "ducks",
component: DucksComponent
},
{
path: "detail/:id",
component: DuckDetailComponent
}
]
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

View File

@ -0,0 +1,11 @@
.duck-link .image {
background-color: black;
width: 64px;
height: 64px;
border-radius: 50%;
margin-right: 1em;
}
.duck-link .small {
margin-bottom: 0;
}

View File

@ -1,4 +1,10 @@
<div *ngFor="let duck of ducks" (click)="gotoDetail(duck)">
{{ duck.color }}
<h3>Duck Dashboard!</h3>
<div class="list-group">
<a *ngFor="let duck of ducks"
class="list-group-item duck-link"
href="#">
<div class="image pull-left"></div>
{{ duck.name }}
<p class="clearfix small">Something.</p>
</a>
</div>
<duck-search></duck-search>

View File

@ -1,27 +1,19 @@
import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { DuckService } from "./duck.service";
import { Duck } from "./models";
@Component({
selector: "dashboard",
templateUrl: "/app/dashboard.component.html"
templateUrl :"app/dashboard.component.html",
styleUrls: ["app/dashboard.component.css"]
})
export class DashboardComponent implements OnInit {
ducks: Duck[] = [];
constructor(private router: Router,
private duckService: DuckService)
{}
constructor(private duckService: DuckService) {}
ngOnInit(): void {
this.duckService.getDucks()
.then(ducks => this.ducks = ducks.slice(1, 5));
}
gotoDetail(duck: Duck): void {
let link = ['/detail', duck.id];
this.router.navigate(link);
.then(ducks => this.ducks = ducks);
}
}

View File

@ -1,12 +1,3 @@
<div *ngIf="duck">
<div>
<label>id: </label>
{{ duck.id }}
</div>
<div>
<label>color: </label>
<input [(ngModel)]="duck.color" placeholder="Color" />
</div>
<button (click)="save()">Save</button>
<button (click)="goBack()">Back</button>
<h2>{{ duck.name }}</h2>
</div>

View File

@ -1,17 +1,22 @@
import { Component, Input, OnInit } from "@angular/core";
import { Component, OnInit} from "@angular/core";
import { ActivatedRoute, Params } from "@angular/router";
import { DuckService } from "./duck.service";
import { Location } from "@angular/common";
import { Duck } from "./models";
import { DuckService } from "./duck.service";
@Component({
moduleId: module.id,
selector: "duck-detail",
templateUrl: "/app/duck-detail.component.html"
templateUrl: "duck-detail.component.html"
})
export class DuckDetailComponent implements OnInit {
constructor(private duckService: DuckService,
private route: ActivatedRoute)
export class DuckDetailComponent {
duck: Duck;
constructor(
private duckService: DuckService,
private route: ActivatedRoute,
private location: Location)
{}
ngOnInit(): void {
@ -19,18 +24,6 @@ export class DuckDetailComponent implements OnInit {
let id = +params['id'];
this.duckService.getDuck(id)
.then(duck => this.duck = duck);
});
})
}
goBack(): void {
window.history.back();
}
save(): void {
this.duckService.update(this.duck)
.then(this.goBack);
}
@Input()
duck: Duck;
}

View File

@ -1,11 +0,0 @@
<div id="search-component">
<h4>Duck search</h4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)">
<div>
<div *ngFor="let duck of ducks | async"
(click)="gotoDetail(duck)"
class="search-result">
{{ duck.color }}
</div>
</div>
</div>

View File

@ -1,43 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { DuckSearchService } from "./duck-search.service";
import { Duck } from "./models";
@Component({
selector: "duck-search",
templateUrl: "/app/duck-search.component.html",
providers: [ DuckSearchService ]
})
export class DuckSearchComponent implements OnInit {
ducks: Observable<Duck[]>;
private searchTerm = new Subject<string>();
constructor(private duckSearchService: DuckSearchService,
private router: Router)
{}
search(term: string): void {
this.searchTerm.next(term);
}
ngOnInit(): void {
this.ducks = this.searchTerm
.debounceTime(300) // wait for 300ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time
? this.duckSearchService.search(term)
: Observable.of<Duck[]>([]))
.catch(error => {
console.log(error);
return Observable.of<Duck[]>([]);
});
}
gotoDetail(duck: Duck): void {
let link = ['/detail', duck.id];
this.router.navigate(link);
}
}

View File

@ -1,15 +0,0 @@
import { Injectable } from "@angular/core";
import { Http, Response } from "@angular/http";
import { Observable } from "rxjs";
import { Duck } from "./models";
@Injectable()
export class DuckSearchService {
constructor (private http: Http) {}
search(term: string): Observable<Duck[]> {
return this.http.get(`app/ducks/?color=${term}`)
.map((r: Response) => r.json().data as Duck[]);
}
}

View File

@ -7,42 +7,11 @@ import { Duck } from "./models";
@Injectable()
export class DuckService {
private ducksUrl = 'app/ducks';
private headers = new Headers({"Content-Type": "application/json"});
private ducksUrl = 'app/ducks';
constructor(private http: Http) {}
private handleError(error: any): Promise<any> {
console.error("An error occured", error);
return Promise.reject(error.message || error);
}
create(color: string): Promise<Duck> {
return this.http.post(this.ducksUrl, JSON.stringify({color: color}), {headers: this.headers})
.toPromise()
.then((res) => res.json().data)
.catch(this.handleError);
}
update(duck: Duck): Promise<Duck> {
const url = `${this.ducksUrl}/${duck.id}`;
return this.http.put(url, JSON.stringify(duck), {headers: this.headers})
.toPromise()
.then(() => duck)
.catch(this.handleError);
}
delete(id: number): Promise<void> {
let url = `${this.ducksUrl}/${id}`;
return this.http.delete(url, {headers: this.headers})
.toPromise()
.then(() => null)
.catch(this.handleError);
}
getDucks(): Promise<Duck[]> {
return this.http.get(this.ducksUrl)
.toPromise()
@ -51,6 +20,20 @@ export class DuckService {
}
getDuck(id: number): Promise<Duck> {
return this.getDucks().then(ducks => ducks.find(duck => duck.id === id));
return this.getDucks()
.then(ducks => ducks.find(duck => duck.id === id));
}
create(name: string): Promise<Duck> {
return this.http.post(this.ducksUrl, JSON.stringify({name: name}), {headers: this.headers})
.toPromise()
.then(res => res.json().data)
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error("An error occured", error);
return Promise.reject(error.message || error);
}
}

View File

@ -1,17 +1,6 @@
<h1>Hello!</h1>
<ul>
<li *ngFor="let duck of ducks" (click)="onSelect(duck)">
{{ duck.color }}
<button (click)="delete(duck); $event.stopPropagation()">Delete</button>
<li *ngFor="let duck of ducks">
<span class="badge">{{ duck.id }}</span>
{{ duck.name }}
</li>
</ul>
<div>
<label>Duck color:</label>
<input #duckColor>
<button (click)="add(duckColor.value); duckColor.value = ''">Add</button>
</div>
<div *ngIf="selectedDuck">
{{ selectedDuck.color }}
<button (click)="gotoDetail(selectedDuck)">Edit</button>
</div>

View File

@ -5,54 +5,42 @@ import { Duck } from "./models";
import { DuckService } from "./duck.service";
@Component({
moduleId: module.id,
selector: "ducks",
templateUrl: "/app/ducks.component.html",
providers: [ DuckService ]
templateUrl: "ducks.component.html"
})
export class DucksComponent implements OnInit {
ducks = [];
export class DucksComponent {
ducks: Duck[];
selectedDuck: Duck;
constructor(private router: Router,
private duckService: DuckService)
constructor(private duckService: DuckService,
private router: Router)
{}
ngOnInit(): void {
this.getDucks();
getDucks(): void
{
this.duckService
.getDucks()
.then(ducks => this.ducks = ducks);
}
getDucks(): void {
this.duckService.getDucks().then(ducks => this.ducks = ducks);
}
add(name: string): void {
name = name.trim();
onSelect(duck: Duck): void {
this.selectedDuck = duck;
}
if (!name) { return; }
gotoDetail(duck: Duck): void {
this.router.navigate(['/detail', duck.id]);
}
add(color: string): void {
// Make sure the color is not empty
color = color.trim();
if (!color) { return; }
this.duckService.create(color)
this.duckService.create(name)
.then(duck => {
this.ducks.push(duck);
this.selectedDuck = null;
});
}
delete(duck: Duck): void {
this.duckService.delete(duck.id)
.then(() => {
this.ducks = this.ducks.filter(d => d !== duck);
ngOnInit(): void {
this.getDucks();
}
if (this.selectedDuck === duck) {
this.selectedDuck = null;
}
});
onSelect(duck: Duck): void {
this.selectedDuck = duck;
}
}

View File

@ -1,11 +1,18 @@
import { InMemoryDbService } from "angular2-in-memory-web-api";
import { InMemoryDbService } from "angular-in-memory-web-api";
export class InMemoryDataService implements InMemoryDbService {
createDb() {
let ducks = [
{ id: 1, color: 'yellow' },
{ id: 2, color: 'blue' },
{ id: 3, color: 'pink' }
{
id: 1,
name: "Fastfingers",
color: "#ee6aa7"
},
{
id: 2,
name: "Lady Pickett",
color: "#8b8b00"
}
];
return {ducks};

View File

@ -1,4 +1,5 @@
export class Duck {
id: number;
name: string;
color: string;
}

View File

@ -1,12 +0,0 @@
// Observable class extensions
import "rxjs/add/observable/of";
import "rxjs/add/observable/throw";
// Observable operators
import "rxjs/add/operator/catch";
import "rxjs/add/operator/debounceTime";
import "rxjs/add/operator/distinctUntilChanged";
import "rxjs/add/operator/do";
import "rxjs/add/operator/filter";
import "rxjs/add/operator/map";
import "rxjs/add/operator/switchMap";

View File

@ -1,29 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<title>Angular 2 QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Rubber Duck Booking Tool</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="styles.css">
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!-- 3. Display the application -->
<body>
<duckbook-front>Loading…</duckbook-front>
<duckbook-front-app>Loading…</duckbook-front-app>
</body>
</html>

View File

@ -3,41 +3,46 @@
"description": "Front-end for the Rubber Duck Booking Tool",
"repository": {
"type": "git",
"url": "https://github.com/gergelypolonkai/duckbook-front"
"url": "https://github.com/gergelypolonkai/duck-booking-tool-front"
},
"version": "1.0.0",
"scripts": {
"start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
"start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
"lite": "lite-server",
"postinstall": "typings install",
"tsc": "tsc",
"tsc:w": "tsc -w",
"typings": "typings"
"tsc:w": "tsc -w"
},
"license": "ISC",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"dependencies": {
"@angular/common": "2.0.0-rc.6",
"@angular/compiler": "2.0.0-rc.6",
"@angular/compiler-cli": "0.6.0",
"@angular/core": "2.0.0-rc.6",
"@angular/forms": "2.0.0-rc.6",
"@angular/http": "2.0.0-rc.6",
"@angular/platform-browser": "2.0.0-rc.6",
"@angular/platform-browser-dynamic": "2.0.0-rc.6",
"@angular/router": "3.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.6",
"@angular/common": "~2.1.1",
"@angular/compiler": "~2.1.1",
"@angular/core": "~2.1.1",
"@angular/forms": "~2.1.1",
"@angular/http": "~2.1.1",
"@angular/platform-browser": "~2.1.1",
"@angular/platform-browser-dynamic": "~2.1.1",
"@angular/router": "~3.1.1",
"@angular/upgrade": "~2.1.1",
"angular-in-memory-web-api": "~0.1.13",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.11",
"systemjs": "0.19.27",
"zone.js": "^0.6.17",
"angular2-in-memory-web-api": "0.0.18",
"bootstrap": "^3.3.6"
"ng2-bootstrap": "^1.1.16",
"reflect-metadata": "^0.1.8",
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.39",
"zone.js": "^0.6.25"
},
"devDependencies": {
"concurrently": "^2.2.0",
"@types/core-js": "^0.9.34",
"@types/node": "^6.0.45",
"concurrently": "^3.0.0",
"lite-server": "^2.2.2",
"typescript": "^1.8.10",
"typings": "^1.3.2"
"typescript": "^2.0.3"
}
}

View File

@ -0,0 +1,14 @@
/* Master Styles */
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
h2, h3 {
color: #444;
font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
}
body {
margin: 2em;
}

View File

@ -1,6 +1,5 @@
/**
* System configuration for Angular 2 samples
* Adjust as necessary for your application needs.
* System configuration for the Rubber Duck Booking Tool
*/
(function (global) {
System.config({
@ -23,7 +22,8 @@
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'ng2-bootstrap/ng2-bootstrap': 'node_modules/ng2-bootstrap/bundles/ng2-bootstrap.umd.js"',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
@ -33,10 +33,6 @@
},
rxjs: {
defaultExtension: 'js'
},
'angular2-in-memory-web-api': {
main: './index.js',
defaultExtension: 'js'
}
}
});

View File

@ -1,7 +0,0 @@
{
"globalDependencies": {
"core-js": "registry:dt/core-js#0.0.0+20160725163759",
"jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
"node": "registry:dt/node#6.0.0+20160831021119"
}
}