مسیریابی در Angular - قسمت پنجم - تعریف Child Routes
نویسنده: وحید نصیری
تاریخ: ۱۳۹۶/۰۲/۱۲ ۹:۲۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<ul class="nav navbar-nav">
<li><a [routerLink]="['/home']">Home</a></li>
<li><a [routerLink]="['/products']">Product List</a></li>
<li><a [routerLink]="['/products', 0, 'edit']">Add Product</a></li>
</ul> <div class="container"> <router-outlet></router-outlet> </div>
>ng g c product/ProductEditInfo >ng g c product/ProductEditTags
export interface IProduct {
id: number;
productName: string;
productCode: string;
category: string;
tags?: string[];
} import { ProductEditTagsComponent } from './product-edit-tags/product-edit-tags.component';
import { ProductEditInfoComponent } from './product-edit-info/product-edit-info.component';
const routes: Routes = [
{ path: 'products', component: ProductListComponent },
{
path: 'products/:id', component: ProductDetailComponent,
resolve: { product: ProductResolverService }
},
{
path: 'products/:id/edit', component: ProductEditComponent,
resolve: { product: ProductResolverService },
children: [
{
path: '',
redirectTo: 'info',
pathMatch: 'full'
},
{
path: 'info',
component: ProductEditInfoComponent
},
{
path: 'tags',
component: ProductEditTagsComponent
}
]
}
]; <div class="panel panel-primary">
<div class="panel-heading">
{{pageTitle}}
</div>
<div class="panel-body" *ngIf="product">
<div class="wizard">
<a [routerLink]="['info']">
Basic Information
</a>
<a [routerLink]="['tags']">
Search Tags
</a>
</div>
<router-outlet></router-outlet>
</div>
<div class="panel-footer">
<div class="row">
<div class="col-md-6 col-md-offset-2">
<span>
<button class="btn btn-primary"
type="button"
style="width:80px;margin-right:10px"
[disabled]="!isValid()"
(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>
</div>
<div class="has-error" *ngIf="errorMessage">{{errorMessage}}</div>
</div>
<a [routerLink]="['/products',product.id,'edit','info']">Info</a>
<a [routerLink]="['info']">Info</a>
this.router.navigate(['/products', this.product.id,'edit','info']);
this.router.navigate(['info', { relativeTo: this.route }]); import { ActivatedRoute } from '@angular/router';
import { NgForm } from '@angular/forms';
import { Component, OnInit, ViewChild } from '@angular/core';
import { IProduct } from './../iproduct';
@Component({
//selector: 'app-product-edit-info',
templateUrl: './product-edit-info.component.html',
styleUrls: ['./product-edit-info.component.css']
})
export class ProductEditInfoComponent implements OnInit {
@ViewChild(NgForm) productForm: NgForm;
errorMessage: string;
product: IProduct;
constructor(private route: ActivatedRoute) { }
ngOnInit(): void {
this.route.parent.data.subscribe(data => {
this.product = data['product'];
if (this.productForm) {
this.productForm.reset();
}
});
}
} <div class="panel-body">
<form class="form-horizontal"
novalidate
#productForm="ngForm">
<fieldset>
<legend>Basic Product Information</legend>
<div class="form-group"
[ngClass]="{'has-error': (productNameVar.touched ||
productNameVar.dirty || product.id !== 0) &&
!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 || product.id !== 0) &&
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 || product.id !== 0) &&
!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 || product.id !== 0) &&
productCodeVar.errors">
<span *ngIf="productCodeVar.errors.required">
Product code is required.
</span>
</span>
</div>
</div>
<div class="has-error" *ngIf="errorMessage">{{errorMessage}}</div>
</fieldset>
</form>
</div>
import { ActivatedRoute } from '@angular/router';
import { IProduct } from './../iproduct';
import { Component, OnInit } from '@angular/core';
@Component({
//selector: 'app-product-edit-tags',
templateUrl: './product-edit-tags.component.html',
styleUrls: ['./product-edit-tags.component.css']
})
export class ProductEditTagsComponent implements OnInit {
errorMessage: string;
newTags = '';
product: IProduct;
constructor(private route: ActivatedRoute) { }
ngOnInit(): void {
this.route.parent.data.subscribe(data => {
this.product = data['product'];
});
}
// Add the defined tags
addTags(): void {
let tagArray = this.newTags.split(',');
this.product.tags = this.product.tags ? this.product.tags.concat(tagArray) : tagArray;
this.newTags = '';
}
// Remove the tag from the array of tags.
removeTag(idx: number): void {
this.product.tags.splice(idx, 1);
}
} <div class="panel-body">
<form class="form-horizontal"
novalidate>
<fieldset>
<legend>Product Search Tags</legend>
<div class="form-group"
[ngClass]="{'has-error': (categoryVar.touched ||
categoryVar.dirty || product.id !== 0) &&
!categoryVar.valid }">
<label class="col-md-2 control-label" for="categoryId">Category</label>
<div class="col-md-8">
<input class="form-control"
id="categoryId"
type="text"
placeholder="Category (required)"
required
minlength="3"
[(ngModel)]="product.category"
name="category"
#categoryVar="ngModel" />
<span class="help-block" *ngIf="(categoryVar.touched ||
categoryVar.dirty || product.id !== 0) &&
categoryVar.errors">
<span *ngIf="categoryVar.errors.required">
A category must be entered.
</span>
<span *ngIf="categoryVar.errors.minlength">
The category must be at least 3 characters in length.
</span>
</span>
</div>
</div>
<div class="form-group"
[ngClass]="{'has-error': (tagVar.touched ||
tagVar.dirty || product.id !== 0) &&
!tagVar.valid }">
<label class="col-md-2 control-label" for="tagsId">Search Tags</label>
<div class="col-md-8">
<input class="form-control"
id="tagsId"
type="text"
placeholder="Search keywords separated by commas"
minlength="3"
[(ngModel)]="newTags"
name="tags"
#tagVar="ngModel" />
<span class="help-block" *ngIf="(tagVar.touched ||
tagVar.dirty || product.id !== 0) &&
tagVar.errors">
<span *ngIf="tagVar.errors.minlength">
The search tag must be at least 3 characters in length.
</span>
</span>
</div>
<div class="col-md-1">
<button type="button"
class="btn btn-default"
(click)="addTags()">
Add
</button>
</div>
</div>
<div class="row col-md-8 col-md-offset-2">
<span *ngFor="let tag of product.tags; let i = index">
<button class="btn btn-default"
style="font-size:smaller;margin-bottom:12px"
(click)="removeTag(i)">
{{tag}}
<span class="glyphicon glyphicon-remove"></span>
</button>
</span>
</div>
<div class="has-error" *ngIf="errorMessage">{{errorMessage}}</div>
</fieldset>
</form>
</div>
ngOnInit(): void {
this.route.parent.data.subscribe(data => {
this.product = data['product'];
if (this.productForm) {
this.productForm.reset();
}
});
} @ViewChild(NgForm) productForm: NgForm;
<form class="form-horizontal" novalidate #productForm="ngForm">
export class ProductEditComponent implements OnInit {
private dataIsValid: { [key: string]: boolean } = {};
isValid(path: string): boolean {
this.validate();
if (path) {
return this.dataIsValid[path];
}
return (this.dataIsValid &&
Object.keys(this.dataIsValid).every(d => this.dataIsValid[d] === true));
}
saveProduct(): void {
if (this.isValid(null)) {
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.';
}
}
validate(): void {
// Clear the validation object
this.dataIsValid = {};
// 'info' tab
if (this.product.productName &&
this.product.productName.length >= 3 &&
this.product.productCode) {
this.dataIsValid['info'] = true;
} else {
this.dataIsValid['info'] = false;
}
// 'tags' tab
if (this.product.category &&
this.product.category.length >= 3) {
this.dataIsValid['tags'] = true;
} else {
this.dataIsValid['tags'] = false;
}
}
} <button class="btn btn-primary"
type="button"
style="width:80px;margin-right:10px"
[disabled]="!isValid()"
(click)="saveProduct()">
Save
</button>