Angular ASP.NET Core MVC view rendering
▌Introduction
So far we had
created components with template or template url. Now the question is, CAN we RENDER MVC VIEW with razor tags and Html helpers in
angular COMPONENT?
The answer is YES!
Let’s try and find it out in this tutorial!
The answer is YES!
Let’s try and find it out in this tutorial!
▌Environment
▋Visual Studio 2015
Update 3
▋Microsoft.AspNetCore.Mvc
1.0.0
▌Implement
▋Create the following MVC controller and views
▋Routing、 modules、components
▋customermvc.main.ts
▋customermvc.app.comp.ts
▋customermvc.route.ts
The routes will include “Index”, “Create” and ”Edit”
routes.
const appRoutes: Routes = [
{ path: 'Basic/CustomerMvc/Index', component: CustomerMvcListComp
},
{ path: 'Basic/CustomerMvc/Create', component: CustomerMvcCreateComp
},
{ path: 'Basic/CustomerMvc/Edit/:id', component: CustomerMvcEditComp
},
{ path: '', redirectTo: '/Basic/CustomerMvc/Index', pathMatch: 'full' }
];
|
We will implement the Index page for example.
▋Set MVC controller/view
Just create the MVC view like it used to be.
▋CustomerMvcController.cs
[Route("[action]")]
public IActionResult Index()
{
return View();
}
|
▋Index.cshtml
@model List<Angular2.Mvc.Core.Models.ViewModel.VmCustomer>
<div>
<input type="button" class="btn btn-primary" value="Create New" (click)="goToCreate()" />
</div>
<br />
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model
=> model.First().Name)
</th>
<th>
@Html.DisplayNameFor(model
=> model.First().Age)
</th>
<th>
@Html.DisplayNameFor(model
=> model.First().Phone)
</th>
<th>
@Html.DisplayNameFor(model
=> model.First().Description)
</th>
<th></th>
</tr>
</thead>
<tbody>
@if (Model != null)
{
foreach (var item in Model)
{
<tr>
<td class="col-sm-2">
@(new
Microsoft.AspNetCore.Html.HtmlString(item.Name))
</td>
<td class="col-sm-2">
@Html.DisplayFor(modelItem
=> item.Age)
</td>
<td class="col-sm-1">
@Html.DisplayFor(modelItem
=> item.Phone)
</td>
<td class="col-sm-2">
@Html.DisplayFor(modelItem
=> item.Description)
</td>
<td class="col-sm-2">
<input type="button" class="btn btn-info" value="Edit" (click)="editCustomer(@item.Id)" />
<input type="button" class="btn btn-danger" value="Delete" (click)="deleteCustomer(@item.Id)" />
</td>
</tr>
}
}
</tbody>
</table>
<div class="alert alert-info" role="alert">
@{
var title = "Hi, " + ViewBag.Description;
}
@title
</div>
|
▋Angular: Component
Since we have the MVC view, lets create the component for
it.
▋customermvc.list.comp.ts
Notice that we should set the templateUrl to the MVC routing path.
The url: “/Basic/CustomerMvc/Create” here is NOT the Angular routing path.
The url: “/Basic/CustomerMvc/Create” here is NOT the Angular routing path.
import {Component, OnInit,
Inject, ElementRef} from '@angular/core';
import {Router} from '@angular/router';
import {Customer} from '../../../class/Customer';
@Component({
selector: 'customermvc-list',
templateUrl: '/Basic/CustomerMvc/List'
})
export class CustomerMvcListComp {
constructor(
private router: Router) {
}
//Get to edit page
private goToCreate() {
this.router.navigate(['Basic/CustomerMvc/Create']);
}
//Get to edit page
private editCustomer(id:
number) {
this.router.navigate(['Basic/CustomerMvc/Edit', id]);
}
private deleteCustomer(id:
number) {
//Remove …
}
}
|
▋Run the application
▋Event Listener
We could add event callback to a DOM in codes by ElementRef class.
For example, we want to let the message popup while user click an image.
▋Create.cshtml
For example, we want to let the message popup while user click an image.
▋Create.cshtml
<img id='tipImg' style='width: 30px; height: 30px;' src='XXX' />
<!--Skip other html in Create page --> |
▋customermvc.create.comp.ts
import {Component, OnInit, ElementRef} from '@angular/core';
@Component({
selector: 'customermvc-create',
templateUrl: '/Basic/CustomerMvc/Create'
})
export class CustomerMvcCreateComp
implements OnInit {
constructor(
private elementRef: ElementRef) {
}
ngOnInit() {
this.addEventListner();
}
private addEventListner() {
let el = this.elementRef.nativeElement.querySelector("#tipImg");
if (el) {
el.addEventListener('click', e => {
e.preventDefault();
this.showTip();
});
}
}
private showTip() {
swal(
'Tip',
'Required information : Name, Phone.'
).then(function () {
});
}
//...
}
|
▋Demo
▌Issues
When I try to navigate to the Edit page with an ID in
angular component, I found it’s impossible to send the ID to MVC controller, so
although the edit component could have the right html but there won’t be any initial
value.
The solution to overcome this issue is using ngModel and
load the initial value by ajax.
▋edit.cshtml
▋edit.cshtml
<input type="text" asp-for="Name" [(ngModel)]="name" class="form-control"/>
|
▋edit component
ngOnInit() {
//Get route parameter
this.route.params.subscribe(params
=> {
let custIdValue = params['id'];
let custId =
+custIdValue; //Equales to parseInt
this.custService.get(custId).then(cust
=> { //By ajax
this.id = cust.Id;
this.name =
cust.Name;
this.age = cust.Age;
this.phone = cust.Phone;
this.description =
cust.Description;
})
});
}
|
Result :
▌Github
▌Reference
N/A
沒有留言:
張貼留言