مسیریابی در Angular - قسمت سوم - پارامترهای مسیریابی
نویسنده: وحید نصیری
تاریخ: ۱۳۹۶/۰۲/۰۹ ۱۲:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
>ng g c product/ProductDetail >ng g c product/ProductEdit
import { ProductEditComponent } from './product-edit/product-edit.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { ProductListComponent } from './product-list/product-list.component';
const routes: Routes = [
{ path: 'products', component: ProductListComponent },
{ path: 'products/:id', component: ProductDetailComponent },
{ path: 'products/:id/edit', component: ProductEditComponent }
]; > ng g i product/IProduct
export interface IProduct {
id: number;
productName: string;
productCode: string;
} >npm install angular-in-memory-web-api --save
"dependencies": {
"angular-in-memory-web-api": "^0.3.1"
}, > ng g cl product/ProductData
import { IProduct } from './iproduct';
import { InMemoryDbService, InMemoryBackendConfig } from 'angular-in-memory-web-api';
export class ProductData implements InMemoryDbService, InMemoryBackendConfig {
createDb() {
let products: IProduct[] = [
{
'id': 1,
'productName': 'Product 1',
'productCode': '0011'
},
{
'id': 2,
'productName': 'Product 2',
'productCode': '0023'
},
{
'id': 5,
'productName': 'Product 5',
'productCode': '0048'
},
{
'id': 8,
'productName': 'Product 8',
'productCode': '0022'
},
{
'id': 10,
'productName': 'Product 10',
'productCode': '0042'
}
];
return { products };
}
} import { ProductData } from './product/product-data';
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
@NgModule({
declarations: [
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
InMemoryWebApiModule.forRoot(ProductData, { delay: 1000 }),
ProductModule,
UserModule,
AppRoutingModule
], >ng g s product/product -m product/product.module
installing service create src\app\product\product.service.spec.ts create src\app\product\product.service.ts update src\app\product\product.module.ts
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/of';
import { IProduct } from './iproduct';
@Injectable()
export class ProductService {
private baseUrl = 'api/products';
constructor(private http: Http) { }
getProducts(): Observable<IProduct[]> {
return this.http.get(this.baseUrl)
.map(this.extractData)
.do(data => console.log('getProducts: ' + JSON.stringify(data)))
.catch(this.handleError);
}
getProduct(id: number): Observable<IProduct> {
if (id === 0) {
return Observable.of(this.initializeProduct());
};
const url = `${this.baseUrl}/${id}`;
return this.http.get(url)
.map(this.extractData)
.do(data => console.log('getProduct: ' + JSON.stringify(data)))
.catch(this.handleError);
}
deleteProduct(id: number): Observable<Response> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
const url = `${this.baseUrl}/${id}`;
return this.http.delete(url, options)
.do(data => console.log('deleteProduct: ' + JSON.stringify(data)))
.catch(this.handleError);
}
saveProduct(product: IProduct): Observable<IProduct> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
if (product.id === 0) {
return this.createProduct(product, options);
}
return this.updateProduct(product, options);
}
private createProduct(product: IProduct, options: RequestOptions): Observable<IProduct> {
product.id = undefined;
return this.http.post(this.baseUrl, product, options)
.map(this.extractData)
.do(data => console.log('createProduct: ' + JSON.stringify(data)))
.catch(this.handleError);
}
private updateProduct(product: IProduct, options: RequestOptions): Observable<IProduct> {
const url = `${this.baseUrl}/${product.id}`;
return this.http.put(url, product, options)
.map(() => product)
.do(data => console.log('updateProduct: ' + JSON.stringify(data)))
.catch(this.handleError);
}
private extractData(response: Response) {
let body = response.json();
return body.data || {};
}
private handleError(error: Response): Observable<any> {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
initializeProduct(): IProduct {
// Return an initialized object
return {
id: 0,
productName: null,
productCode: null
};
}
} private baseUrl = 'api/products';
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { ProductService } from './../product.service';
import { IProduct } from './../iproduct';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {
pageTitle = 'Product List';
errorMessage: string;
products: IProduct[];
constructor(private productService: ProductService,
private route: ActivatedRoute) { }
ngOnInit(): void {
this.productService.getProducts()
.subscribe(products => this.products = products,
error => this.errorMessage = <any>error);
}
} <div class="panel panel-default">
<div class="panel-heading">
{{pageTitle}}
</div>
<div class="panel-body">
<div class="has-error" *ngIf="errorMessage">{{errorMessage}}</div>
<div class="table-responsive">
<table class="table" *ngIf="products && products.length">
<thead>
<tr>
<th>Product</th>
<th>Code</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let product of products">
<td><a [routerLink]="['/products', product.id]">
{{product.productName}}
</a>
</td>
<td>{{ product.productCode}}</td>
<td>
<a class="btn btn-primary" [routerLink]="['/products', product.id, 'edit']">
Edit
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<a [routerLink]="['/products', product.id]">
{{product.productName}}
</a> <a class="btn btn-primary" [routerLink]="['/products', product.id, 'edit']">
Edit
</a> <li>
<a [routerLink]="['/products', 0, 'edit']">Add Product</a>
</li> saveProduct(product: IProduct): Observable<IProduct> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
if (product.id === 0) {
return this.createProduct(product, options);
}
return this.updateProduct(product, options);
} this.router.navigate(['products', this.product.id]);
let id = +this.route.snapshot.params['id'];
{ path: 'products/:id', component: ProductDetailComponent } <a [routerLink]="['/products', product.id]">{{product.productName}}</a> this.route.params.subscribe(
params => {
let id = +params['id'];
this.getProduct(id);
}
); import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ProductService } from './../product.service';
import { IProduct } from './../iproduct';
@Component({
selector: 'app-product-detail',
templateUrl: './product-detail.component.html',
styleUrls: ['./product-detail.component.css']
})
export class ProductDetailComponent implements OnInit {
pageTitle = 'Product Detail';
product: IProduct;
errorMessage: string;
constructor(private productService: ProductService,
private route: ActivatedRoute) { }
ngOnInit(): void {
let id = +this.route.snapshot.params['id'];
this.getProduct(id);
}
getProduct(id: number) {
this.productService.getProduct(id).subscribe(
product => this.product = product,
error => this.errorMessage = <any>error);
}
}
<div class="panel panel-primary" *ngIf="product">
<div class="panel-heading" style="font-size:large">
{{pageTitle + ": " + product.productName}}
</div>
<div class="panel-body">
<div>
Name: {{product.productName}}
</div>
<div>
Code: {{product.productCode}}
</div>
<div class="has-error" *ngIf="errorMessage">{{errorMessage}}</div>
</div>
<div class="panel-footer">
<a class="btn btn-default" [routerLink]="['/products']">
<i class="glyphicon glyphicon-chevron-left"></i> Back
</a>
<a class="btn btn-primary" style="width:80px;margin-left:10px"
[routerLink]="['/products', product.id, 'edit']">
Edit
</a>
</div>
</div> import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
CommonModule,
FormsModule,
ProductRoutingModule
] import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ProductService } from './../product.service';
import { IProduct } from './../iproduct';
@Component({
selector: 'app-product-edit',
templateUrl: './product-edit.component.html',
styleUrls: ['./product-edit.component.css']
})
export class ProductEditComponent implements OnInit {
pageTitle = 'Product Edit';
product: IProduct;
errorMessage: string;
constructor(private productService: ProductService,
private route: ActivatedRoute,
private router: Router) { }
ngOnInit(): void {
let id = +this.route.snapshot.params['id'];
this.getProduct(id);
}
getProduct(id: number): void {
this.productService.getProduct(id)
.subscribe(
(product: IProduct) => this.onProductRetrieved(product),
(error: any) => this.errorMessage = <any>error
);
}
onProductRetrieved(product: IProduct): void {
this.product = product;
if (this.product.id === 0) {
this.pageTitle = 'Add Product';
} else {
this.pageTitle = `Edit Product: ${this.product.productName}`;
}
}
deleteProduct(): void {
if (this.product.id === 0) {
// Don't delete, it was never saved.
this.onSaveComplete();
} else {
if (confirm(`Really delete the product: ${this.product.productName}?`)) {
this.productService.deleteProduct(this.product.id)
.subscribe(
() => this.onSaveComplete(`${this.product.productName} was deleted`),
(error: any) => this.errorMessage = <any>error
);
}
}
}
saveProduct(): void {
if (true === true) {
this.productService.saveProduct(this.product)
.subscribe(
() => this.onSaveComplete(`${this.product.productName} was saved`),
(error: any) => this.errorMessage = <any>error
);
} else {
this.errorMessage = 'Please correct the validation errors.';
}
}
onSaveComplete(message?: string): void {
if (message) {
// TODO: show msg
}
// Navigate back to the product list
this.router.navigate(['/products']);
}
} <div class="panel panel-primary">
<div class="panel-heading">
{{pageTitle}}
</div>
<div class="panel-body" *ngIf="product">
<form class="form-horizontal" novalidate (ngSubmit)="saveProduct()" #productForm="ngForm">
<fieldset>
<div class="form-group" [ngClass]="{'has-error': (productNameVar.touched ||
productNameVar.dirty) &&
!productNameVar.valid }">
<label class="col-md-2 control-label" for="productNameId">Product Name</label>
<div class="col-md-8">
<input class="form-control" id="productNameId" type="text" placeholder="Name (required)"
required minlength="3" [(ngModel)]=product.productName
name="productName" #productNameVar="ngModel" />
<span class="help-block" *ngIf="(productNameVar.touched ||
productNameVar.dirty) &&
productNameVar.errors">
<span *ngIf="productNameVar.errors.required">
Product name is required.
</span>
<span *ngIf="productNameVar.errors.minlength">
Product name must be at least three characters.
</span>
</span>
</div>
</div>
<div class="form-group" [ngClass]="{'has-error': (productCodeVar.touched ||
productCodeVar.dirty) &&
!productCodeVar.valid }">
<label class="col-md-2 control-label" for="productCodeId">Product Code</label>
<div class="col-md-8">
<input class="form-control" id="productCodeId" type="text" placeholder="Code (required)"
required [(ngModel)]=product.productCode
name="productCode" #productCodeVar="ngModel" />
<span class="help-block" *ngIf="(productCodeVar.touched ||
productCodeVar.dirty) &&
productCodeVar.errors">
<span *ngIf="productCodeVar.errors.required">
Product code is required.
</span>
</span>
</div>
</div>
<div class="form-group">
<div class="col-md-4 col-md-offset-2">
<span>
<button class="btn btn-primary"
type="submit"
style="width:80px;margin-right:10px"
[disabled]="!productForm.valid"
(click)="saveProduct()">
Save
</button>
</span>
<span>
<a class="btn btn-default"
[routerLink]="['/products']">
Cancel
</a>
</span>
<span>
<a class="btn btn-default"
(click)="deleteProduct()">
Delete
</a>
</span>
</div>
</div>
</fieldset>
</form>
<div class="has-error" *ngIf="errorMessage">{{errorMessage}}</div>
</div>
</div> ngOnInit(): void {
let id = +this.route.snapshot.params['id'];
this.getProduct(id);
}
ngOnInit(): void {
this.route.params.subscribe(
params => {
let id = +params['id'];
this.getProduct(id);
}
);
} // For Angular 4+
let id = +this.route.snapshot.paramMap.get('id');
this.getProduct(id);
// OR
this.route.paramMap.subscribe(params => {
let id = +params['id'];
this.getProduct(id);
}); { path: 'products/:name/:code', component: ProductListComponent } [routerLink]="['/products', productName, productCode]"
{ path: 'products', component: ProductListComponent }, [routerLink]="['/products', {name: productName, code: productCode}]" http://localhost:4200/products;name=Controller;code=gmg
let name = this.route.snapshot.params['name']; let code = this.route.snapshot.params['code'];
http://localhost:42000/products/5?filterBy=product1
{ path: 'products', component: ProductListComponent} <a [routerLink] = "['/products', product.id]"
[queryParams] = "{ filterBy: 'er', showImage: true }">
{{product.productName}}
</a> this.router.navigate(['/products'],
{
queryParams: { filterBy: 'er', showImage: true}
}
); [preserveQueryParams] = "true"
<a class="btn btn-default"
[routerLink]="['/products']"
[preserveQueryParams]="true">
<i class="glyphicon glyphicon-chevron-left"></i> Back
</a> this.router.navigate(['/products'],
{ queryParamsHandling: 'preserve'}
); var filter = this.route.snapshot.queryParams['filterBy'] || ''; var showImage = this.route.snapshot.queryParams['showImage'] === 'true';
>ng g p product/ProductFilter
import { PipeTransform, Pipe } from '@angular/core';
import { IProduct } from './iproduct';
@Pipe({
name: 'productFilter'
})
export class ProductFilterPipe implements PipeTransform {
transform(value: IProduct[], filterBy: string): IProduct[] {
filterBy = filterBy ? filterBy.toLocaleLowerCase() : null;
return filterBy ? value.filter((product: IProduct) =>
product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1) : value;
}
} <div class="panel-body">
<div class="row">
<div class="col-md-2">Filter by:</div>
<div class="col-md-4">
<input type="text" [(ngModel)]="listFilter" />
</div>
</div>
<div class="row" *ngIf="listFilter">
<div class="col-md-6">
<h3>Filtered by: {{listFilter}} </h3>
</div>
</div> <tr *ngFor="let product of products | productFilter:listFilter">
<td><a [routerLink]="['/products', product.id]"
[queryParams]="{filterBy: listFilter}">
{{product.productName}}
</a>
</td>
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {
listFilter: string;
ngOnInit(): void {
this.listFilter = this.route.snapshot.queryParams['filterBy'] || '';