In traditional web applications, the client (browser) initiates the communication with the server by requesting a page. The server then processes the request and sends the HTML of the page to the client. In subsequent interactions with the page, for example the user navigates to a link or submits a form with data, a new request is sent to the server and the flow starts again. The server processes the request and sends a new page to the browser in response to the new action requested by the client.
Image 1.
In Single-Page Applications (SPAs) the entire page is loaded into the browser after the initial request, but subsequent interactions take place using Ajax requests. This means that the browser must update only the portion of the page that has changed; there is no need to reload the entire page. The SPA approach reduces the time taken by the application to respond to user actions, resulting in a more fluid experience.
Single-Page Applications (SPAs) are Web apps that load a single HTML page and dynamically update that page as the user interacts with the app.
Image 2.
Now we will learn this by creating a sample application. In this SPA example I will do CRUD operations on the Student table using the Web API and MVC.
Image 3.
The following is my Data Table in design mode:
Image 4.
The script of my Student Table is:
- CREATE TABLE [dbo].[Student](
- [StudentID] [int] IDENTITY(1,1) NOT NULL,
- [Name] [varchar](50) NULL,
- [Email] [varchar](500) NULL,
- [Class] [varchar](50) NULL,
- [EnrollYear] [varchar](50) NULL,
- [City] [varchar](50) NULL,
- [Country] [varchar](50) NULL,
- CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
- (
- [StudentID] ASC
- )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- ) ON [PRIMARY]
- GO
- SET ANSI_PADDING OFF
- GO
Image 5.
Select Web -> ASP.NET Web Application then provide I a name. Then click OK.
Image 6.
Select Single Page Application from the template option. Then click OK.
Now right-click on the Models Folder then select Add -> ADO.NET Entity Data Model.
Image 7.
Image 8.
Provide It a name.
Image 9.
Image 10.
Image 11.
Image 12.
Image 13.
Now we will add AngularJS references using NuGet. Right-click on Solution Explorer.
Image 14.
Image 15.
Image 16.
Image 17.
Now we will add a Web API so right-click on the controller folder then select Add -> Controller.
Image 18.
Image 19.
Image 20.
ManageStudentsInfoAPIController.cs is:
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Data.Entity;
- using System.Data.Entity.Infrastructure;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Web.Http;
- using System.Web.Http.Description;
- using SPA_MVC_StudentApp.Models;
- namespace SPA_MVC_StudentApp.Controllers
- {
- public class ManageStudentsInfoAPIController : ApiController
- {
- private SchoolManagementEntities db = new SchoolManagementEntities();
- // GET: api/ManageStudentsInfoAPI
- public IQueryable<Student> GetStudent()
- {
- return db.Student;
- }
- // GET: api/ManageStudentsInfoAPI/5
- [ResponseType(typeof(Student))]
- public IHttpActionResult GetStudent(int id)
- {
- Student student = db.Student.Find(id);
- if (student == null)
- {
- return NotFound();
- }
- return Ok(student);
- }
- // PUT: api/ManageStudentsInfoAPI/5
- [ResponseType(typeof(void))]
- public IHttpActionResult PutStudent(int id, Student student)
- {
- if (!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
- if (id != student.StudentID)
- {
- return BadRequest();
- }
- db.Entry(student).State = EntityState.Modified;
- try
- {
- db.SaveChanges();
- }
- catch (DbUpdateConcurrencyException)
- {
- if (!StudentExists(id))
- {
- return NotFound();
- }
- else
- {
- throw;
- }
- }
- return StatusCode(HttpStatusCode.NoContent);
- }
- // POST: api/ManageStudentsInfoAPI
- [ResponseType(typeof(Student))]
- public IHttpActionResult PostStudent(Student student)
- {
- if (!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
- db.Student.Add(student);
- db.SaveChanges();
- return CreatedAtRoute("DefaultApi", new { id = student.StudentID }, student);
- }
- // DELETE: api/ManageStudentsInfoAPI/5
- [ResponseType(typeof(Student))]
- public IHttpActionResult DeleteStudent(int id)
- {
- Student student = db.Student.Find(id);
- if (student == null)
- {
- return NotFound();
- }
- db.Student.Remove(student);
- db.SaveChanges();
- return Ok(student);
- }
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- db.Dispose();
- }
- base.Dispose(disposing);
- }
- private bool StudentExists(int id)
- {
- return db.Student.Count(e => e.StudentID == id) > 0;
- }
- }
- }
Image 21.
Image 22.
Image 23.
After adding ManageStudentInfo Controller we need to add a view.
Image 24.
Index.cshtml
- @{
- ViewBag.Title = "SPA";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
- <body data-ng-app="ApplicationModule">
- <div>
- <div>
- <div>
- <table cellpadding="5" cellspacing="6" width="100%" style="background-color:whitesmoke; border:solid 4px green;">
- <tr>
- <td style="border: solid 1px gray; width:170px; text-align:center;"><a href="showstudents"> Show All Students </a></td>
- <td style="border: solid 1px gray; width:170px; text-align:center;"><a href="addstudent"> Add New Student </a></td>
- <td></td>
- </tr>
- </table>
- </div>
- <div>
- <div data-ng-view></div>
- </div>
- </div>
- </div>
- </body>
- @section scripts{
- <script type="text/javascript" src="@Url.Content("~/Scripts/angular.js")"></script>
- <script type="text/javascript" src="@Url.Content("~/Scripts/angular-route.min.js")"></script>
- <script type="text/javascript" src="@Url.Content("~/MyScripts/Module.js")"></script>
- <script src="~/MyScripts/Services.js"></script>
- <script type="text/javascript" src="@Url.Content("~/MyScripts/ShowStudentsController.js")"></script>
- <script type="text/javascript" src="@Url.Content("~/MyScripts/AddStudentController.js")"></script>
- <script type="text/javascript" src="@Url.Content("~/MyScripts/EditStudentController.js")"></script>
- <script type="text/javascript" src="@Url.Content("~/MyScripts/DeleteStudentController.js")"></script>
- }
Here in this example we will perform the following operations:
- ShowAllStudent
- AddStudent
- EditStudent
- DeleteStudent
Image 25.
ShowAllStudent.cshtml
- <table><tr><td height="10px"></td></tr></table>
- <table cellpadding="4" cellspacing="4" width="90%" align="center"
- style="background-color: skyblue; border:solid 2px red; padding-top:20px;">
- <thead>
- <tr style="background-color:#F5F5F5;">
- <th>Student ID</th>
- <th>Name</th>
- <th>Email</th>
- <th>Class</th>
- <th>Enroll Year</th>
- <th>City</th>
- <th>Country</th>
- <th></th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <tr data-ng-repeat="Stud in Students">
- <td>{{Stud.studentID}}</td>
- <td>{{Stud.name}}</td>
- <td>{{Stud.email}}</td>
- <td>{{Stud.class}}</td>
- <td>{{Stud.enrollYear}}</td>
- <td>{{Stud.city}}</td>
- <td>{{Stud.country}}</td>
- <td><a ng-click="editStudent(Stud.studentID)">Edit</a></td>
- <td><a ng-click="deleteStudent(Stud.studentID)">Delete</a></td>
- </tr>
- </tbody>
- </table>
AddStudent.cshtml
- @{
- ViewBag.Title = "Add New Student";
- }
- <table><tr><td height="10px"></td></tr></table>
- <table cellpadding="4" cellspacing="4" width="70%" align="center" style="background-color: skyblue;
- border:solid 2px red; padding-top:20px;">
- <tr><td colspan="3" style="background-color:gray; font-size:18pt;
- font-weight:bold; height:30px; text-align:center;">Add New Student</td></tr>
- <tr>
- <td style="text-align:right;">Student ID</td>
- <td><input type="text" ng-model="StudentID" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Name</td>
- <td><input type="text" ng-model="Name" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Email</td>
- <td><input type="text" ng-model="Email" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Class</td>
- <td><input type="text" ng-model="Class" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Enroll Year</td>
- <td><input type="text" ng-model="EnrollYear" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">City</td>
- <td><input type="text" ng-model="City" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Country</td>
- <td><input type="text" ng-model="Country" /> </td>
- </tr>
- <tr>
- <td></td>
- <td>
- <input type="button" value="Save" data-ng-click="save()" />
- </td>
- </tr>
- </table>
- @{
- ViewBag.Title = "Delete Student";
- }
- <table><tr><td height="10px"></td></tr></table>
- <table cellpadding="4" cellspacing="4" width="70%" align="center" style="background-color: skyblue; border:solid 2px red; padding-top:20px;">
- <tr><td colspan="3" style="background-color:gray; font-size:18pt; font-weight:bold; height:30px; text-align:center;">Delete Student Information</td></tr>
- <tr>
- <td style="text-align:right;">Student ID</td>
- <td>{{Student.studentID}} </td>
- </tr>
- <tr>
- <td style="text-align:right;">Name # </td>
- <td> {{Student.name}} </td>
- </tr>
- <tr>
- <td style="text-align:right;">Email # </td>
- <td>{{Student.email}} </td>
- </tr>
- <tr>
- <td style="text-align:right;">Class # </td>
- <td>{{Student.class}} </td>
- </tr>
- <tr>
- <td style="text-align:right;">Enroll Year # </td>
- <td>{{Student.enrollYear}} </td>
- </tr>
- <tr>
- <td style="text-align:right;">City # </td>
- <td>{{Student.city}} </td>
- </tr>
- <tr>
- <td style="text-align:right;">Country # </td>
- <td>{{Student.country}} </td>
- </tr>
- <tr>
- <td></td>
- <td>
- <input type="button" value="Delete" ng-click="delete()" />
- </td>
- </tr>
- </table>
- @{
- ViewBag.Title = "Edit Student";
- }
- <table><tr><td height="10px"></td></tr></table>
- <table cellpadding="4" cellspacing="4" width="70%" align="center" style="background-color: skyblue; border:solid 2px red; padding-top:20px;">
- <tr><td colspan="3" style="background-color:gray; font-size:18pt; font-weight:bold; height:30px; text-align:center;">Edit Student Information</td></tr>
- <tr>
- <td style="text-align:right;">Student ID</td>
- <td><input type="text" ng-model="Student.studentID" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Name</td>
- <td><input type="text" ng-model="Student.name" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Email</td>
- <td><input type="text" ng-model="Student.email" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Class</td>
- <td><input type="text" ng-model="Student.class" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Enroll Year</td>
- <td><input type="text" ng-model="Student.enrollYear" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">City</td>
- <td><input type="text" ng-model="Student.city" /> </td>
- </tr>
- <tr>
- <td style="text-align:right;">Country</td>
- <td><input type="text" ng-model="Student.country" /> </td>
- </tr>
- <tr>
- <td></td>
- <td>
- <input type="button" value="Save" ng-click="save()" />
- <br />
- <div>{{error}}</div>
- </td>
- </tr>
- </table>
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- namespace SPA_MVC_StudentApp.Controllers
- {
- public class ManageStudentInfoController : Controller
- {
- // GET: ManageStudentInfo
- public ActionResult Index()
- {
- return View();
- }
- public ActionResult AddNewStudent()
- {
- return PartialView("AddStudent");
- }
- public ActionResult ShowStudents()
- {
- return PartialView("ShowAllStudent");
- }
- public ActionResult EditStudent()
- {
- return PartialView("EditStudent");
- }
- public ActionResult DeleteStudent()
- {
- return PartialView("DeleteStudent");
- }
- }
- }
And add the following JavaScript files.
- Module.js
- Services.js
- ShowStudentsController.js
- AddStudentController.js
- EditStudentController.js
- DeleteStudentController.js
Module.js
- var app = angular.module("ApplicationModule", ["ngRoute"]);
- app.factory("ShareData", function () {
- return { value: 0 }
- });
- //Showing Routing
- app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
- debugger;
- $routeProvider.when('/showstudents',
- {
- templateUrl: 'ManageStudentInfo/ShowStudents',
- controller: 'ShowStudentsController'
- });
- $routeProvider.when('/addstudent',
- {
- templateUrl: 'ManageStudentInfo/AddNewStudent',
- controller: 'AddStudentController'
- });
- $routeProvider.when("/editStudent",
- {
- templateUrl: 'ManageStudentInfo/EditStudent',
- controller: 'EditStudentController'
- });
- $routeProvider.when('/deleteStudent',
- {
- templateUrl: 'ManageStudentInfo/DeleteStudent',
- controller: 'DeleteStudentController'
- });
- $routeProvider.otherwise(
- {
- redirectTo: '/'
- });
- $locationProvider.html5Mode(true).hashPrefix('!')
- }]);
- app.service("SPACRUDService", function ($http) {
- //Read all Students
- this.getStudents = function () {
- return $http.get("/api/ManageStudentInfoAPI");
- };
- //Fundction to Read Student by Student ID
- this.getStudent = function (id) {
- return $http.get("/api/ManageStudentInfoAPI/" + id);
- };
- //Function to create new Student
- this.post = function (Student) {
- var request = $http({
- method: "post",
- url: "/api/ManageStudentInfoAPI",
- data: Student
- });
- return request;
- };
- //Edit Student By ID
- this.put = function (id, Student) {
- var request = $http({
- method: "put",
- url: "/api/ManageStudentInfoAPI/" + id,
- data: Student
- });
- return request;
- };
- //Delete Student By Student ID
- this.delete = function (id) {
- var request = $http({
- method: "delete",
- url: "/api/ManageStudentInfoAPI/" + id
- });
- return request;
- };
- });
- app.controller('ShowStudentsController', function ($scope, $location, SPACRUDService, ShareData) {
- loadAllStudentsRecords();
- function loadAllStudentsRecords()
- {
- var promiseGetStudent = SPACRUDService.getStudents();
- promiseGetStudent.then(function (pl) { $scope.Students = pl.data },
- function (errorPl) {
- $scope.error = errorPl;
- });
- }
- //To Edit Student Information
- $scope.editStudent = function (StudentID) {
- ShareData.value = StudentID;
- $location.path("/editStudent");
- }
- //To Delete a Student
- $scope.deleteStudent = function (StudentID) {
- ShareData.value = StudentID;
- $location.path("/deleteStudent");
- }
- });
- app.controller('AddStudentController', function ($scope, SPACRUDService) {
- $scope.StudentID = 0;
- $scope.save = function () {
- var Student = {
- StudentID: $scope.StudentID,
- Name: $scope.Name,
- Email: $scope.Email,
- Class: $scope.Class,
- EnrollYear: $scope.EnrollYear,
- City: $scope.City,
- Country: $scope.Country
- };
- var promisePost = SPACRUDService.post(Student);
- promisePost.then(function (pl) {
- alert("Student Saved Successfully.");
- },
- function (errorPl) {
- $scope.error = 'failure loading Student', errorPl;
- });
- };
- });
- app.controller("EditStudentController", function ($scope, $location, ShareData, SPACRUDService) {
- getStudent();
- function getStudent() {
- var promiseGetStudent = SPACRUDService.getStudent(ShareData.value);
- promiseGetStudent.then(function (pl)
- {
- $scope.Student = pl.data;
- },
- function (errorPl) {
- $scope.error = 'failure loading Student', errorPl;
- });
- }
- $scope.save = function () {
- var Student = {
- StudentID: $scope.Student.studentID,
- Name: $scope.Student.name,
- Email: $scope.Student.email,
- Class: $scope.Student.class,
- EnrollYear: $scope.Student.enrollYear,
- City: $scope.Student.city,
- Country: $scope.Student.country
- };
- var promisePutStudent = SPACRUDService.put($scope.Student.studentID, Student);
- promisePutStudent.then(function (pl)
- {
- $location.path("/showstudents");
- },
- function (errorPl) {
- $scope.error = 'failure loading Student', errorPl;
- });
- };
- });
- app.controller("DeleteStudentController", function ($scope, $location, ShareData, SPACRUDService) {
- getStudent();
- function getStudent() {
- var promiseGetStudent = SPACRUDService.getStudent(ShareData.value);
- promiseGetStudent.then(function (pl) {
- $scope.Student = pl.data;
- },
- function (errorPl) {
- $scope.error = 'failure loading Student', errorPl;
- });
- }
- $scope.delete = function () {
- var promiseDeleteStudent = SPACRUDService.delete(ShareData.value);
- promiseDeleteStudent.then(function (pl) {
- $location.path("/showstudents");
- },
- function (errorPl) {
- $scope.error = 'failure loading Student', errorPl;
- });
- };
- });
Image 26.
Now click on Show All Students.
Image 27.
Now click on Add New Student.
Image 28.
Image 29.
Now click on Edit.
Image 30.
Image 31.
No comments:
Post a Comment