examples: added an example of a crud app

This commit is contained in:
vsavkin 2015-07-01 10:51:36 -07:00
parent 0598226e24
commit 3a8e1661fa
9 changed files with 498 additions and 0 deletions

View File

@ -0,0 +1,5 @@
library examples.e2e_test.order_management_spec;
main() {
}

View File

@ -0,0 +1,10 @@
import {verifyNoBrowserErrors} from 'angular2/src/test_lib/e2e_util';
describe('Order Management CRUD', function() {
var URL = 'examples/src/order_management/index.html';
it('should work', function() {
browser.get(URL);
verifyNoBrowserErrors();
});
});

View File

@ -0,0 +1,5 @@
library examples.e2e_test.person_management_spec;
main() {
}

View File

@ -0,0 +1,10 @@
import {verifyNoBrowserErrors} from 'angular2/src/test_lib/e2e_util';
describe('Person Management CRUD', function() {
var URL = 'examples/src/person_management/index.html';
it('should work', function() {
browser.get(URL);
verifyNoBrowserErrors();
});
});

View File

@ -0,0 +1,19 @@
<!doctype html>
<html>
<head>
<title>Order Management</title>
<style>
.warning {
background-color: yellow;
}
</style>
</head>
<body>
<order-management-app>
Loading...
</order-management-app>
$SCRIPTS$
</body>
</html>

View File

@ -0,0 +1,210 @@
import {
bootstrap,
onChange,
NgIf,
NgFor,
Component,
Directive,
View,
Ancestor,
NgValidator,
forwardRef,
Binding,
EventEmitter
} from 'angular2/angular2';
import {formDirectives} from 'angular2/forms';
import {ListWrapper} from 'angular2/src/facade/collection';
import {reflector} from 'angular2/src/reflection/reflection';
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
/**
* You can find the Angular 1 implementation of this example here:
* https://github.com/wardbell/ng1DataBinding
*/
// ---- model
class OrderItem {
constructor(public orderItemId: number, public orderId: number, public productName: string,
public qty: number, public unitPrice: number) {}
get total(): number { return this.qty * this.unitPrice; }
}
class Order {
constructor(public orderId: number, public customerName: string, public limit: number,
private dataService: DataService) {}
get items(): OrderItem[] { return this.dataService.itemsFor(this); }
get total(): number { return this.items.map(i => i.total).reduce((a, b) => a + b); }
}
// ---- services
var _nextId = 1000;
class DataService {
orderItems: OrderItem[];
orders: Order[];
currentOrder: Order = null;
constructor() {
this.orders = [
new Order(_nextId++, "J. Coltrane", 100, this),
new Order(_nextId++, "B. Evans", 200, this)
];
this.orderItems = [
new OrderItem(_nextId++, this.orders[0].orderId, "Bread", 5, 1),
new OrderItem(_nextId++, this.orders[0].orderId, "Brie", 5, 2),
new OrderItem(_nextId++, this.orders[0].orderId, "IPA", 5, 3),
new OrderItem(_nextId++, this.orders[1].orderId, "Mozzarella", 5, 2),
new OrderItem(_nextId++, this.orders[1].orderId, "Wine", 5, 3)
];
}
itemsFor(order: Order): OrderItem[] {
return ListWrapper.filter(this.orderItems, i => i.orderId === order.orderId);
}
addItemForOrder(order: Order): void {
this.orderItems.push(new OrderItem(_nextId++, order.orderId, "", 0, 0));
}
deleteItem(item: OrderItem): void { ListWrapper.remove(this.orderItems, item); }
}
// ---- components
@Component({selector: 'order-list-cmp'})
@View({
template: `
<h1>Orders</h1>
<div *ng-for="#order of orders" [class.warning]="order.total > order.limit">
<div>
<label>Customer name:</label>
{{order.customerName}}
</div>
<div>
<label>Limit: <input [(ng-model)]="order.limit" type="number" placeholder="Limit"></label>
</div>
<div>
<label>Number of items:</label>
{{order.items.length}}
</div>
<div>
<label>Order total:</label>
{{order.total}}
</div>
<button (click)="select(order)">Select</button>
</div>
`,
directives: [formDirectives, NgFor]
})
class OrderListComponent {
orders: Order[];
constructor(private service: DataService) { this.orders = service.orders; }
select(order: Order): void { this.service.currentOrder = order; }
}
@Component({selector: 'order-item-cmp', properties: ['item'], events: ['delete']})
@View({
template: `
<div>
<div>
<label>Product name: <input [(ng-model)]="item.productName" type="text" placeholder="Product name"></label>
</div>
<div>
<label>Quantity: <input [(ng-model)]="item.qty" type="number" placeholder="Quantity"></label>
</div>
<div>
<label>Unit Price: <input [(ng-model)]="item.unitPrice" type="number" placeholder="Unit price"></label>
</div>
<div>
<label>Total:</label>
{{item.total}}
</div>
<button (click)="onDelete()">Delete</button>
</div>
`,
directives: [formDirectives]
})
class OrderItemComponent {
item: OrderItem;
delete = new EventEmitter();
onDelete(): void { this.delete.next(this.item); }
}
@Component({selector: 'order-details-cmp'})
@View({
template: `
<div *ng-if="order !== null">
<h1>Selected Order</h1>
<div>
<label>Customer name: <input [(ng-model)]="order.customerName" type="text" placeholder="Customer name"></label>
</div>
<div>
<label>Limit: <input [(ng-model)]="order.limit" type="number" placeholder="Limit"></label>
</div>
<div>
<label>Number of items:</label>
{{order.items.length}}
</div>
<div>
<label>Order total:</label>
{{order.total}}
</div>
<h2>Items</h2>
<button (click)="addItem()">Add Item</button>
<order-item-cmp *ng-for="#item of order.items" [item]="item" (delete)="deleteItem(item)"></order-item-cmp>
</div>
`,
directives: [formDirectives, OrderItemComponent, NgFor, NgIf]
})
class OrderDetailsComponent {
constructor(private service: DataService) {}
get order(): Order { return this.service.currentOrder; }
deleteItem(item: OrderItem): void { this.service.deleteItem(item); }
addItem(): void { this.service.addItemForOrder(this.order); }
}
@Component({selector: 'order-management-app', viewInjector: [DataService]})
@View({
template: `
<order-list-cmp></order-list-cmp>
<order-details-cmp></order-details-cmp>
`,
directives: [OrderListComponent, OrderDetailsComponent]
})
class OrderManagementApplication {
}
export function main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrap(OrderManagementApplication);
}

View File

@ -0,0 +1,19 @@
<!doctype html>
<html>
<head>
<title>Person Management</title>
<style>
.ng-touched.ng-invalid {
border-color: red;
}
</style>
</head>
<body>
<person-management-app>
Loading...
</person-management-app>
$SCRIPTS$
</body>
</html>

View File

@ -0,0 +1,218 @@
import {
bootstrap,
onChange,
NgIf,
NgFor,
Component,
Directive,
View,
Ancestor,
NgValidator,
forwardRef,
Binding
} from 'angular2/angular2';
import {formDirectives} from 'angular2/forms';
import {RegExpWrapper, print, isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
import {reflector} from 'angular2/src/reflection/reflection';
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
/**
* You can find the Angular 1 implementation of this example here:
* https://github.com/wardbell/ng1DataBinding
*/
// ---- model
var _nextId = 1;
class Person {
personId: number;
mom: Person;
dad: Person;
friends: Person[];
constructor(public firstName: string, public lastName: string, public yearOfBirth: number) {
this.personId = _nextId++;
this.firstName = firstName;
this.lastName = lastName;
this.mom = null;
this.dad = null;
this.friends = [];
this.personId = _nextId++;
}
get age(): number { return 2015 - this.yearOfBirth; }
get fullName(): string { return `${this.firstName} ${this.lastName}`; }
get friendNames(): string { return this.friends.map(f => f.fullName).join(', '); }
}
// ---- services
class DataService {
currentPerson: Person;
persons: Person[];
constructor() {
this.persons = [
new Person('Victor', 'Savkin', 1930),
new Person('Igor', 'Minar', 1920),
new Person('John', 'Papa', 1910),
new Person('Nancy', 'Duarte', 1910),
new Person('Jack', 'Papa', 1910),
new Person('Jill', 'Papa', 1910),
new Person('Ward', 'Bell', 1910),
new Person('Robert', 'Bell', 1910),
new Person('Tracy', 'Ward', 1910),
new Person('Dan', 'Wahlin', 1910)
];
this.persons[0].friends = [0, 1, 2, 6, 9].map(_ => this.persons[_]);
this.persons[1].friends = [0, 2, 6, 9].map(_ => this.persons[_]);
this.persons[2].friends = [0, 1, 6, 9].map(_ => this.persons[_]);
this.persons[6].friends = [0, 1, 2, 9].map(_ => this.persons[_]);
this.persons[9].friends = [0, 1, 2, 6].map(_ => this.persons[_]);
this.persons[2].mom = this.persons[5];
this.persons[2].dad = this.persons[4];
this.persons[6].mom = this.persons[8];
this.persons[6].dad = this.persons[7];
this.currentPerson = this.persons[0];
}
}
// ---- components
@Component({selector: 'full-name-cmp'})
@View({
template: `
<h1>Edit Full Name</h1>
<div>
<form>
<div>
<label>
First: <input [(ng-model)]="person.firstName" type="text" placeholder="First name">
</label>
</div>
<div>
<label>
Last: <input [(ng-model)]="person.lastName" type="text" placeholder="Last name">
</label>
</div>
<div>
<label>{{person.fullName}}</label>
</div>
</form>
</div>
`,
directives: [formDirectives]
})
class FullNameComponent {
constructor(private service: DataService) {}
get person(): Person { return this.service.currentPerson; }
}
@Component({selector: 'person-detail-cmp'})
@View({
template: `
<h2>{{person.fullName}}</h2>
<div>
<form>
<div>
<label>First: <input [(ng-model)]="person.firstName" type="text" placeholder="First name"></label>
</div>
<div>
<label>Last: <input [(ng-model)]="person.lastName" type="text" placeholder="Last name"></label>
</div>
<div>
<label>Year of birth: <input [(ng-model)]="person.yearOfBirth" type="number" placeholder="Year of birth"></label>
Age: {{person.age}}
</div>\
<div *ng-if="person.mom != null">
<label>Mom:</label>
<input [(ng-model)]="person.mom.firstName" type="text" placeholder="Mom's first name">
<input [(ng-model)]="person.mom.lastName" type="text" placeholder="Mom's last name">
{{person.mom.fullName}}
</div>
<div *ng-if="person.dad != null">
<label>Dad:</label>
<input [(ng-model)]="person.dad.firstName" type="text" placeholder="Dad's first name">
<input [(ng-model)]="person.dad.lastName" type="text" placeholder="Dad's last name">
{{person.dad.fullName}}
</div>
<div *ng-if="person.friends.length > 0">
<label>Friends:</label>
{{person.friendNames}}
</div>
</form>
</div>
`,
directives: [formDirectives, NgIf]
})
class PersonsDetailComponent {
constructor(private service: DataService) {}
get person(): Person { return this.service.currentPerson; }
}
@Component({selector: 'persons-cmp'})
@View({
template: `
<h1>FullName Demo</h1>
<div>
<ul>
<li *ng-for="#person of persons">
<label (click)="select(person)">{{person.fullName}}</label>
</li>
</ul>
<person-detail-cmp></person-detail-cmp>
</div>
`,
directives: [formDirectives, PersonsDetailComponent, NgFor]
})
class PersonsComponent {
persons: Person[];
constructor(private service: DataService) { this.persons = service.persons; }
select(person: Person): void { this.service.currentPerson = person; }
}
@Component({selector: 'person-management-app', viewInjector: [DataService]})
@View({
template: `
<button (click)="switchToEditName()">Edit Full Name</button>
<button (click)="switchToPersonList()">Person List</button>
<full-name-cmp *ng-if="mode == 'editName'"></full-name-cmp>
<persons-cmp *ng-if="mode == 'personList'"></persons-cmp>
`,
directives: [FullNameComponent, PersonsComponent, NgIf]
})
class PersonManagementApplication {
mode: string;
switchToEditName(): void { this.mode = 'editName'; }
switchToPersonList(): void { this.mode = 'personList'; }
}
export function main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrap(PersonManagementApplication);
}

View File

@ -40,6 +40,8 @@ const kServedPaths = [
'examples/src/benchpress',
'examples/src/model_driven_forms',
'examples/src/template_driven_forms',
'examples/src/person_management',
'examples/src/order_management',
'examples/src/gestures',
'examples/src/hello_world',
'examples/src/http',