We will start building the routing with angular2 router.
[Area("Basic")]
[Route("Basic/[controller]")]
public class CustomerController : Controller
{
[Route("[action]")]
public IActionResult Index()
{
return View();
}
}
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
If you hadn't set the base url on _Layout.cshtml
, don't forget it!
<head>
<base href="/">
<!--Skip....-->
</head>
Like we created "Hello world" module and component in Day 5, we need to create the following typescripts.
customer.module.ts
: imports necessary modules and declarations.customer.component.ts
: our component.Customer.main.ts
: bootstrapping and target the browser platform.import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {CustomerAppModule} from './customer.app.module';
import {enableProdMode} from '@angular/core';
platformBrowserDynamic().bootstrapModule(CustomerAppModule);
In order to use the angular router library, import Routes
and RouterModule
from @angular/router
.
Furthermore, use the directive: router-outlet
as the template.
import { Component, OnInit } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
@Component({
selector: 'customer-app',
template: '<router-outlet></router-outlet>'
})
export class CustomerAppComponent implements OnInit {
ngOnInit() {
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {CustomerAppComponent } from './customer.app.component';
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
BrowserModule,
HttpModule,
RouterModule.forRoot([]) //The routes should be set here!
],
declarations: [CustomerAppComponent],
bootstrap: [CustomerAppComponent]
})
export class CustomerAppModule { }
Update Index.cshtml to load /app/Basic/Customer/customer.main.js
and put customer-app
inside.
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<hr />
<customer-app>
<div><p><img src="~/images/gif/ajax-loader.gif" /> Please wait ...</p></div>
</customer-app>
@section Scripts {
<script>
System.config({
map: {app: 'app/Basic/Customer'},
packages: {app: {main:'customer.main.js',defaultExtension: 'js'}}
});
System.import('app/customer.main').then(null, console.error.bind(console));
</script>
}
In this sample, we will have the following pages :
So we first create the above components and html and will implement the real content in the next few days.
For example, the index component
should be looked like this…
import {Component, OnInit} from '@angular/core';
import {Routes} from "@angular/router";
@Component({
selector: 'customer-index',
templateUrl: '/app/Basic/Customer/customer-index.component.html'
})
export class CustomerIndexComponent implements OnInit {
title: string;
constructor() {
this.title = "Customers:Index";
}
ngOnInit() {
}
}
<h3>{{title}}</h3>
<hr />
<ul>
<li>
<a [routerLink]="['/Basic/Customer/Create']">Go to Create</a>
</li>
<li>
<a [routerLink]="['/Basic/Customer/Edit']">Go to Edit</a>
</li>
</ul>
Notice that in
[routerLink]
, the name should be "/" + "The route path".
Set the routes in RouterModule.forRoot()
and don't forget to import the component and declare them!
//Skip...
import {CustomerIndexComponent} from './customer-index.component';
import {CustomerCreateComponent} from './customer-create.component';
import {CustomerEditComponent} from './customer-edit.component';
@NgModule({
imports: [
//Skip...
RouterModule.forRoot([
{ path: 'Basic/Customer/Index', component: CustomerIndexComponent },
{ path: 'Basic/Customer/Create', component: CustomerCreateComponent },
{ path: 'Basic/Customer/Edit', component: CustomerEditComponent },
{ path: '', redirectTo: '/Basic/Customer/Index', pathMatch: 'full' }
])
],
declarations: [CustomerAppComponent, CustomerIndexComponent, CustomerCreateComponent, CustomerEditComponent],
bootstrap: [CustomerAppComponent]
})
export class CustomerAppModule { }
Notice that when we want to edit a customer, we need to let the Customer Edit Component
know which customer we are editing.
There are at least two ways to achieve the goal: Send customer id to Edit Component.
Here we will use url parameter for sending the customer's id.
First let's update the RouterModule
settings.
RouterModule.forRoot([
//...
{ path: 'Basic/Customer/Edit/:id', component: CustomerEditComponent }
])
The event of clicking the [Edit]
button on any data is as following.
private editCustomer(item: Customer) {
this.router.navigate(['Basic/Customer/Edit', item.Id]);
}
And the html should be like this,
<input type="button" class="btn btn-info" value="Edit" (click)="editCustomer(item)" />
So that when we click the [Edit]
button on a customer data, we will navigate tohttp://localhost:4240/Basic/Customer/Edit/11
And how to get the parameter value from Url? The interface ActivatedRoute will do us the favor.
//...
import {Router, ActivatedRoute} from '@angular/router';
@Component({
selector: 'customer-edit',
providers: [CustomerService, RestUriService],
templateUrl: '/app/Basic/Customer/customer-edit.component.html'
})
export class CustomerEditComponent implements OnInit {
//...
constructor(
private router: Router,
private route: ActivatedRoute) {
//...
}
ngOnInit() {
this.route.params.subscribe(params => {
let custIdValue = params['id'];
let custId = +custIdValue; //Equales to parseInt
console.log("query id = " + +custIdValue);
});
}
}
We can now start implementing our content and services of SPA.
But first, let's create some fake data and style our pages.
We will do the following works:
ngFor
to display them.navigate
function to change current route.import {Component, OnInit} from '@angular/core';
import {Router} from '@angular/router';
@Component({
selector: 'customer-index',
templateUrl: '/app/Basic/Customer/customer-index.component.html'
})
export class CustomerIndexComponent implements OnInit {
title: string;
customers: any[];
constructor(private router:Router) {
this.title = "Customers:Index";
this.customers = CUSTOMERS;
}
ngOnInit() {
}
//Go to create page
private goToCreate() {
this.router.navigate(['Basic/Customer/Create']);
}
}
const CUSTOMERS: any[] =
[{ "Id": 1, "Name": "<b>JB</b>", "Phone": "0933XXXXXX", "Age": 35 }
//...
];
<input type="button" class="btn btn-primary" value="Create New" (click)="goToCreate()" />
<!--Skip some html-->
<tr *ngFor="let item of customers; let sn=index">
<td class="col-sm-1 text-center">{{item.Id}}</td>
<td class="col-sm-2" [innerHtml]="item.Name">
</td>
<td class="col-sm-2">{{item.Phone}}</td>
<td class="col-sm-1">{{item.Age}}</td>
<td class="col-sm-2">
<input type="button" class="btn btn-info" value="Edit" (click)="editCustomer(item)" />
<input type="button" class="btn btn-danger" value="Delete" (click)="deleteCustomer(item)" />
</td>
</tr>
In the next day-sharing, we will use the current SPA and build advanced content for it.