ایجاد یک اپلیکیشن تک صفحه ای (SPA) با استفاده از AngularJS و WebAPI

چهارشنبه 23 دی 1394

برنامه های تک صفحه ای به طور فزاینده در حال محبوب شدن هستند. سایت هایی که از کارکرد برنامه های تک صفحه ای استفاده می کنند، احساسی در شما ایجاد می کنند که در حال کار با اپلیکیشن های موبایل و تبلت هستید. AngularJS به شما توانایی ایجاد اینگونه از برنامه ها را می دهد. در این مقاله می خواهیم یک اپلیکیشن ساده تک صفحه ای با تکنولوژی Web API و AngularJS ایجاد کنیم که عملیات CRUD را پیاده سازی می کند.

ایجاد یک اپلیکیشن تک صفحه ای (SPA) با استفاده از AngularJS و WebAPI

تکنولوژی هایی که در این مقاله مورد استفاده قرار می گیرند عبارتند از: ASP.NET Web API ،AngularJS  و Bootstrap می باشند. IDE مورد نظر در این نمونه برنامه Visual Studio2013 می باشد و از پایگاه داده Localdb استفاده می شود.

SPA اپلیکیشنی است که در یک صفحه تکی(single) نشان داده شده و یک پنجره غنی تر به کاربر ارائه می دهد، و به صورت تاثیر گذاری عملکرد وب سایت را افزایش دهد.

فریم ورک  Web API بهترین انتخاب برای سرویس های HTTP توسعه یافته می باشد. این روش را  باعث می شود به طیف وسیع تری از کلاینت ها مانند مرورگرهای استفاده شده در ابزارهای متحرک دست پیدا کنیم.

این آموزش شامل تست پروژه نیست. این مقاله آموزش می دهد که چگونه می توانیم ASP.NET Web API را در AngularJS استفاده کنیم.

SPA چیست؟

Single Page Application یا SPA اپلیکیشنی است که تجربه کاربر را در استفاده از HTML5 و AJAX بالا می برد. همانطور که در شکل زیر نشان داده شده است، چرخه حیات SPA را با صفحات وب سنتی مورد مقایسه قرار داده ایم. در این شکل به راحتی می توانیم مشاهده کنیم که SPA ازیک postback/reload اضافی با ارسال درخواست AJAX و دریافت پاسخ به صورت JSON اجتناب می کند.

رویکرد مرحله به مرحله ایجاد یک اپلیکیشن SPA با استفاده از AngularJS و ASP.NET Web API

حالا می خواهیم به صورت مرحله به مرحله ایجاد یک SPA با انجام تمام عملیات CRUD را توضیح دهیم.

مرحله 1: یک ASP.NET Web Application جدید بسازید و نام آن را انتخاب کرده و کلید OK را بزنید:

صفحه بعدی از شما می خواهد که template یا قالب پروژه مورد نظر را انتخاب کنید. لطفا Project Template را برای MVC انتخاب کرده و سپس OK را بزنید.

یک solution جدید در Visual Studio ایجاد خواهد شد.

مرحله 2: در فولدر App_Start یک پایگاه داده محلی با نام Company ایجاد کنید سپس بر روی App_Start راست کلیک کرده و “Add -> New Item” را انتخاب کنید.

گزینه Data را از سمت چپ انتخاب و SQL Server Database را کلیک کنید و نام آن را Students.mdf قرار داده و دکمه Add را از صفحه زیر بزنید.

مرحله 3: حالا پایگاه داده شما آماده است و وقت آن است که جدول students را در پایگاه داده ایجاد کنید.

تا اینجا ما با موفقیت یک جدول EmployeeInfo با فیلدهای Id, EmpName, EmpNo, Salary, Designation, DeptName ایجاد کرده ایم.

برای نگهداری ساده تر اطلاعات بیشتر فیلدها را با نوع  text در نظر گرفته ایم.

مرحله 4: حالا وقت آن است که یک ADO.NET Entity Data Model ایجاد کنیم. این یک Entity framework Database Context برای دستیابی به پایگاه داده ایجاد خواهد کرد.

 5 مرحله پیش رو برای ایجاد یک ADO.NET Entity Data Model می باشد.

1. گزینه add new item را در پوشه Models انتخاب کرده و یک ADO.NET Entity Data Model به آن اضافه کنید.

2. ADO.NET Entity Data Model را انتخاب کرده و نام آن را StudentsDB قرار دهید.

3. گزینه EF Designer From Database را انتخاب کنید (این گزینه به تنظیمات اجازه می دهد که  Entity Framework SQL ای که کلاینت در اینجا استفاده می کند را بشناسد).

4. پایگاه داده ای که ایجاد شده است را انتخاب کنید.

5. حالا در مرحله نهایی جداول پایگاه داده را به Context مربوط به ADO.NET Entity Data Model اضافه می کنیم.

مرحله 5: حالا پروژه را Build کرده و یک Web API Controller با Scaffolding و با استفاده از پایگاه داده محلی کلاس Students ایجاد می کنیم.

1. بر روی پوشه کنترلر راست کلیک کرده و با Add یک کنترلر اضافه می کنیم:

2. گزینه WEB API 2 Controller with actions, using Entity Framework را انتخاب کنید:

موجودیت Company را برای فرایند Scaffolding انتخاب کرده و نام کنترلر را CompanyAPIController قرار دهید.

مرحله 6: WebApiConfig برای تعریف API URL Routing مانند زیر تعریف کنید:

مرحله 7: مطمئن شوید که Web API routing  و Bundling  شما در Global.asax به صورت زیر تعریف شده باشد:

مرحله 8: AngularJS Nuget Package را به پروژه خود اضافه می کنیم:

ما متوجه خواهیم شد که برخی از script ها که در پوشه script اضافه شده اند مرتبط با AngularJS هستند.

مرحله 9: یک پوشه در script با عنوان MyScripts ایجاد کرده و سه فایل اسکریپت دیگر برای ماژول Students خودمان اضافه می کنیم که نام آنها را به صورت زیر قرار می دهیم:

Module.js

Service.js

Controller.js

اجازه دهید با Module.js شروع کنیم که محتوای آن در زیر آمده است:

var app;
( function () {
app = angular.module( "StudentModule" , []);
})();

در اینجا ما یک ماژول Students در Angularjs داریم.

علاوه براین ما در اینجا ماژول سرویس AngularJS Student را توصیف کرده ایم که برای دسترسی به Web API ایجاد کرده بودیم. حالا اجازه دهید سرویسی که برای دسترسی به ASP.NET Web API را ایجاد کردیم نشان دهیم:

در زیر محتوای Service.js آمده است:

app.service( 'StudentService' , function ($http) {
//Create new record
this .post = function (Student) {
var request = $http({
method: "post" ,
url: "/api/StudentsAPI" ,
data: Student
});
return request;
}
//Get Single Records
this .get = function (Id) {
return $http.get( "/api/StudentsAPI/" + Id);
}
//Get All Students
this .getStudents = function () {
return $http.get( "/api/StudentsAPI" );
}
//Update the Record
this .put = function (Id, Student) {
var request = $http({
method: "put" ,
url: "/api/StudentsAPI/" + Id,
data: Student
});
return request;
}
//Delete the Record
this .delete = function (Id) {
var request = $http({
method: "delete" ,
url: "/api/StudentsAPI/" + Id
});
return request;
}
});

حالا می خواهیم Angular students controller را برای رویدادهای روی صفحه به شما نشان دهیم:

در زیر محتوای Controller.js آورده شده است:

controller( 'studentController' , function ($scope, StudentService) {
$scope.IsNewRecord = 1; //The flag for the new record
loadRecords();
//Function to load all Student records
function loadRecords() {
var promiseGet = StudentService.getStudents(); //The MEthod Call from service
promiseGet.then( function (pl) { $scope.Students = pl.data },
function (errorPl) {
$log.error( 'failure loading Student' , errorPl);
});
}
//The Save scope method use to define the Student object.
//In this method if IsNewRecord is not zero then Update Student else
//Create the Student information to the server
$scope.save = function () {
var Student = {
Id: $scope.Id,
StudentName: $scope.StudentName,
StudentRollNo: $scope.StudentRollNo,
StudentDepartment: $scope.StudentDepartment,
StudentbatchNo: $scope.StudentbatchNo,
StudentYear: $scope.StudentYear
};
//If the flag is 1 the it si new record
if ($scope.IsNewRecord === 1) {
var promisePost = StudentService.post(Student);
promisePost.then( function (pl) {
$scope.Id = pl.data.Id;
loadRecords();
}, function (err) {
console.log( "Err" + err);
});
} else { //Else Edit the record
var promisePut = StudentService.put($scope.Id, Student);
promisePut.then( function (pl) {
$scope.Message = "Updated Successfully" ;
loadRecords();
}, function (err) {
console.log( "Err" + err);
});
}
};
//Method to Delete
$scope.delete = function () {
var promiseDelete = StudentService.delete($scope.Id);
promiseDelete.then( function (pl) {
$scope.Message = "Deleted Successfully" ;
$scope.Id = 0;
$scope.StudentName = "" ;
$scope.StudentRollNo = "" ;
$scope.StudentDepartment = "" ;
$scope.StudentbatchNo = "" ;
$scope.StudentYear = "" ;
loadRecords();
}, function (err) {
console.log( "Err" + err);
});
}
//Method to Get Single Student based on Id
$scope.get = function (Student) {
var promiseGetSingle = StudentService.get(Student.Id);
promiseGetSingle.then( function (pl) {
var res = pl.data;
$scope.Id = res.Id;
$scope.StudentName = res.StudentName;
$scope.StudentRollNo = res.StudentRollNo;
$scope.StudentDepartment = res.StudentDepartmen;
$scope.StudentbatchNo = res.StudentbatchNo;
$scope.StudentYear = res.StudentYear;
$scope.IsNewRecord = 0;
},
function (errorPl) {
console.log( 'failure loading Student' , errorPl);
});
}
//Clear the Scopr models
$scope.clear = function () {
$scope.IsNewRecord = 1;
$scope.Id = 0;
$scope.StudentName = "" ;
$scope.StudentRollNo = "" ;
$scope.StudentDepartment = "" ;
$scope.StudentbatchNo = "" ;
$scope.StudentYear = "" ;
}
});

مرحله 10: حالا اجازه دهید یک کنترلر Student خالی برای فقط صفحه View از single page application ایجاد می کنیم:

مرحله 11: برخی از اصلاحات متنی از View مربوط به Layout مشترک را انجام داده ایم.

 Layout جدید به صورت زیر است:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                </ul>
                @Html.Partial("_LoginPartial")
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

این تغییرات متنی کلی و اضافه کردن فایل های اسکریپت angular می باشد.

مرحله 12: حالا اجازه دهید EmployeeInfo view را در index action اضافه کرده و آن را به بوت استرپ متصل کنیم. ما از bootstrap designing در این نمونه برنامه استفاده کرده ایم.

@{
ViewBag.Title = "Index" ;
}
<style type ="text/css">
.tablehover
{
cursor : pointer ;
}
<div class ="container">
<div class ="row" ngcontroller ="studentController">
<div class ="collg4 colmd4 colsm6 colxs12">
<form >
<div class ="formgroup">
<label for ="exampleInputEmail1"> Id
<input type ="text" class ="formcontrol" id ="Id" placeholder ="Enter student ID" readonly ="readonly" ngmodel ="Id">

< div class ="formgroup">
<label for ="StudentName"> Student Name
<input type ="text" class ="formcontrol" id ="StudentName" placeholder ="Enter student Name" required ngmodel ="StudentName">

<div class ="formgroup">
<label for ="StudentRollNo"> Student Roll No
<input type ="text" class ="formcontrol" id ="StudentRollNo" placeholder ="Enter student Roll No" required ngmodel ="StudentRollNo">

<div class ="formgroup">
<label for ="StudentDepartment"> Student Department
<input type ="text" class ="formcontrol" id ="StudentDepartment" placeholder ="Enter student Department" required ngmodel ="StudentDepartment">

<div class ="formgroup">
<label for ="StudentbatchNo"> Student batch No
<input type ="text" class ="formcontrol" id ="StudentbatchNo" placeholder ="Enter student Batch No" required ngmodel ="StudentbatchNo">

<div class ="formgroup">
<label for ="StudentYear"> Student Year
<input type ="text" class ="formcontrol" id ="StudentYear" placeholder ="Enter student Year" required ngmodel ="StudentYear"><button type ="submit" class ="btn btninfo" id ="new" value ="New" ngclick ="clear()"> New
<button type ="submit" class ="btn btninfo" id ="save" value ="Save" ngclick ="save()"> Save
<button type ="submit" class ="btn btninfo" id ="delete" value ="Delete" ngclick ="delete()"> Delete<div class ="collg8 colmd8 colsm6 colxs12">

<table class ="table tablehover textprimary">
<caption > Students List.
<thead >
<tr>
<th> Id
<th> Student Name
<th> Student Roll No
<th> Student Department
<th> Student Batch No
<th> Student Year

<tbody ngrepeat ="Std in Students">
<tr ngclick ="get(Std)">
<td> < span> {{ Std.Id }}
<td> < span> {{ Std.StudentName }}
<td> < span> {{ Std.StudentRollNo }}
<td> < span> {{ Std.StudentDepartment }}
<td> < span> {{ Std.StudentbatchNo }}
<td> < span> {{ Std.StudentYear }}

<div class =&rdquo;collg12 colmd12 colsm12 colxs12&Prime;>< span class =&rdquo;textdanger&rdquo;>
{{ Message }}</ span ></ div>
</ div>
</ div>

مرحله 13: از آنجاییکه این یک Single Page Application می باشد باید Students Controlle را انتخاب کرده و متد Index را روی پیش فرض قرار دهید:

حالا وب سایت شما آماده است، ابتدا باید برنامه را build کرده و سپس آن را اجرا کنید که خروجی را به صورت زیر مشاهده خواهید کرد:

آموزش angular

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید