examples: added an example of a crud app
This commit is contained in:
parent
0598226e24
commit
3a8e1661fa
|
@ -0,0 +1,5 @@
|
|||
library examples.e2e_test.order_management_spec;
|
||||
|
||||
main() {
|
||||
|
||||
}
|
|
@ -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();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
library examples.e2e_test.person_management_spec;
|
||||
|
||||
main() {
|
||||
|
||||
}
|
|
@ -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();
|
||||
});
|
||||
});
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue