شروع کار با AngularJS (بخش اول)

سه شنبه 11 اسفند 1394

در این مقاله مرحله به مرحله نحوه استفاده از AngularJS را بررسی کرده و یک فرم ثبت نام و ورود ساده اما کاربردی را با استفاده از آن پیاده سازی خواهیم کرد.

شروع کار با  AngularJS (بخش اول)

برای شروع یک پروژه از نوع  MVC با انتخاب New Project سپس  Web و بعد از آن ASP.net Web Application  ایجاد میکنیم. در پنجره بعد قالب آن را  MVC انتخاب میکنیم.  می دانیم که قالب پیش فرض  MVC چیزهای زیادی دارد که به برخی از آنها نیاز داریم اما بعضی را بکار نخواهیم برد. پس  Pakage Manager Console  را باز کرده و دستورات زیر را در آن اجرا میکنیم.

هر یک از دستورات زیر را در آن اجرا میکنیم.

Uninstall-Package Microsoft.jQuery.Unobtrusive.Validation

Uninstall-Package jQuery.Validation

Uninstall-Package jQuery

Uninstall-Package Modernizr

Uninstall-Package Respond

Uninstall-Package bootstrap

سپس کلاس  BundleConfig.cs را به صورت زیر آپدیت میکنیم.

using System.Web.Optimization;

namespace AwesomeAngularMVCApp
{
    public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/site.css"));

            BundleTable.EnableOptimizations = true;
        }
    }
}

فایلهای زیر را از کنترلر حذف میکنیم.

AccountController.cs

ManageController.cs

دایرکتوریهای زیر را نیز از پوشه  View  حذف میکنیم.

Account

Manage

Shared

سپس _ViewStart.cshtml  را نیز از پوشه  View  و از داخل پوشه  Home  دو فایل  About.cshtml و Contact.cshtml را حذف میکنیم.

از کنترلر  HomeController متدهای زیر را حذف میکنیم.

About

Contact

سپس به مسیر  Views > Home >Index.cshtml رفته و هر چیزی که درون آن است پاک میکنیم. به همین صورت در پوشه  Content محتوای  Site.css را نیز پاک میکنیم.

چرا همه چیز را حذف کردیم؟ ویژوال استودیو همه کتابخانه هایی که برای احراز هویت و ... لازم است را با انتخاب قالب  MVC اضافه میکند. حذف کتابخانه های HTML/Javascript که مورد نیاز نیست نسبت به ایجاد یک پروژه خالی و اضافه کردن منابعی که نیاز داریم بسیار سریعتر است.

در index.cshtml کدهای زیر را قرار می دهیم.

<!DOCTYPE html>
<html ng-app>
<head>
    <title ng-bind="helloAngular"></title>
</head>
<body>
    
    <input type="text" ng-model="helloAngular" />
    <h1>{{helloAngular}}</h1>
    
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
</body>
</html>

با کلید f5 برنامه را اجرا میکنیم. هنگامی که در  textbox  موجود در صفحه چیزی نوشته شود، نتیجه به صورت زیر خواهد بود.

اگر چیزی شبیه به {{helloAngular}} مشاهده کنیم، جایی در پروژه اشتباهی رخ داده است. در chrome می توانید آن را با استفاده از  F12 و انتخاب تب Console مشاهده کنید. در زیر به دلیل اشتباه نوشتن آدرس برنامه کار نخواهد کرد

کد HTMLکه در index نوشته شد کاملا یک  برنامه  Angular  است.  کاری که ما میکنیم بارگذاری زمان اجرای  Angular و تعریف عنصر مدل است. مدل به سه مکان محدود می شود : عنوان صفحه ، محتوای تگ h1 و مقدار ویژگی کنترل متن ورودی  . ویرایش textbox  سبب تغییر در دو مکان دیگر می شود

مثال بالا یک برنامه ساده و پایه ای  Angular  را نشان می دهد، اما این نوشتن برنامه Angular  در دنیای واقعی محسوب نمی شود.

برای بالا بردن سطح برنامه نوشته شده به صورت زیر عمل میکنیم.

ابتدا یک دایرکتوری در  Script با نام  Controllers ایجاد میکنیم.

یک فایل جاوااسکریپت را در خود پوشه  Script با نام برنامه خود ایجاد میکنیم. در اینجا  AwesomeAngularMVCApp.js  است.

یک فایل جاوااسکریپت درون مسیر  Scipt ->Controllers با نام LandingPageController.js اضافه میکنیم.

اکنون یک  Bundle  را به صورت زیر درون  Bundle.config اضافه میکینم.

bundles.Add(new ScriptBundle("~/bundles/AwesomeAngularMVCApp")
    .IncludeDirectory("~/Scripts/Controllers", "*.js")
    .Include("~/Scripts/AwesomeAngularMVCApp.js"));

این  Bundle  را بعد از تگ اسکریپت angular.min  اضافه میکنیم.

<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script

اکنون کدها را در کنترلر LandingPageController را به صورت زیر می نویسیم.

var LandingPageController = function ($scope) {
    $scope.models = {
        helloAngular: 'برنامه نویسان'
    };
}

// The $inject property of every controller (and pretty much every other type of object in Angular) needs to be a string array equal to the controllers arguments, only as strings
LandingPageController.$inject = ['$scope'];

بعد از آن عناصر برنامه خود را تنظیم میکنیم. و کنترلر را به آن معرفی میکنیم. بنابراین کدهای زیر را در AwesomeAngularMVCApp.js قرار می دهیم.

var AwesomeAngularMVCApp = angular.module('AwesomeAngularMVCApp', []);

AwesomeAngularMVCApp.controller('LandingPageController', LandingPageController);

اکنون homepage View  خود را با برنامه انگولار و کنترلر  Landing Page  ارتباط می دهیم.

<!DOCTYPE html>
<html ng-app="AwesomeAngularMVCApp" ng-controller="LandingPageController">
<head>
    <title ng-bind="models.helloAngular"></title>
</head>
<body>
    <input type="text" ng-model="models.helloAngular" />
    <h1>{{models.helloAngular}}</h1>

    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
    @Scripts.Render("~/bundles/AwesomeAngularMVCApp")
</body>
</html>

نتیجه به صورت زیر خواهد بود:

با مسیریابی ، فریمورک های MVC مانند angular  بسیار قدرتمند عمل میکنند. و برای ساخت برنامه های تک صفحه ای بکار می روند.

یک  div در صفحه Landing  خود قرار دادیم که به انگولار می گوید هر زمان آدرس مطابق یک الگوی خاص بود ، محتوای فایل  HTML را درون این  div  قرار دهد.

برای اضافه کردن بعضی مسیریابی ها به صورت زیر عمل میکنیم.

ابتدا به ماژول  ngRoute نیاز داریم .

سپس آن  div را به صفحه Landing درون تگ  body قبل از تگ  Script  اضافه میکنیم.

در آخر سه لینک برای صفحه  Landing قرار می دهیم که وقتی کلیک شوند مسیر را آپدیت خواهند کرد و  View مناسب را درون تگ  Div  نمایش خواهند داد.

<!DOCTYPE html>
<html ng-app="AwesomeAngularMVCApp" ng-controller="LandingPageController">
<head>
    <title ng-bind="models.helloAngular"></title>
</head>
<body>
    <h1>{{models.helloAngular}}</h1>

    <ul>
        <li><a href="/#/routeOne">مسیر 1</a></li>
        <li><a href="/#/routeTwo">مسیر 2</a></li>
        <li><a href="/#/routeThree">مسیر 3</a></li>
    </ul>

    <div ng-view></div>

    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-route.min.js"></script>
    @Scripts.Render("~/bundles/AwesomeAngularMVCApp")
    </body>
</html>

اکنون می خواهیم مسیر ها را به برنامه معرفی کنیم. این کار در تابع تنظیمات ماژول برنامه انجام می شود. در اینجا به صورت زیر می باشد.

var AwesomeAngularMVCApp = angular.module('AwesomeAngularMVCApp', ['ngRoute']);

AwesomeAngularMVCApp.controller('LandingPageController', LandingPageController);

var configFunction = function ($routeProvider) {
    $routeProvider.
        when('/routeOne', {
            templateUrl: 'routesDemo/one'
        })
        .when('/routeTwo', {
            templateUrl: 'routesDemo/two'
        })
        .when('/routeThree', {
            templateUrl: 'routesDemo/three'
        });
}
configFunction.$inject = ['$routeProvider'];

AwesomeAngularMVCApp.config(configFunction);

اما این  View  هنوز وجود ندارد. در دایرکتوری کنترلر MVC کنترلری با نام RoutesDemoController ایجاد میکنیم و سه متد را با نام های  One, Two  و  Three در آن قرار می دهیم.

using System.Web.Mvc;

namespace AwesomeAngularMVCApp.Controllers
{
    public class RoutesDemoController : Controller
    {
        public ActionResult One()
        {
            return View();
        }

        public ActionResult Two()
        {
            return View();
        }

        public ActionResult Three()
        {
            return View();
        }
    }
}

بر روی هر یک از نمونه های  return View کلیک راست کرده و گزینه  Add View  را انتخاب میکنیم. این  View  ها را به صورت  PartialView  ایجاد میکنیم و محتوایی برای آنها قرار می دهیم.

برنامه را اجرا کنید. قادر خواهید بود بر روی هر یک از لینکها کلیک کنید و محتوای آنها را ببینید.

میخواهیم مسیر 2 را اصلاح کنیم و برای آن پارامتری را قرار دهیم. متد آن را در کنترلر به صورت زیر تغییر می دهیم.

public ActionResult Two(int donuts = 1)
{
    ViewBag.Donuts = donuts;
    return View();
}

اکنون  View  آن را به صورت زیر تغییر می دهیم.

<div>
    
    <h3> مسیر 2 : </h3>
    <br/>
    <h2> در سایت ما می توانید مقالات و ویدیوهای آموزشی را مشاهده کنید</h2>
    @for (var i = 0; i < ViewBag.Donuts; i++)
    {
        <p>می خواهید برنامه نویسی یاد بگیرید؟ </p>
    }
</div>

اکنون باید این پارامتر را به angular معرفی کینم. تابع  Config  را در AwesomeAngularMVCApp به صورت زیر تغییر می دهیم.

Hide   Copy Code

var configFunction = function ($routeProvider) {
    $routeProvider.
        when('/routeOne', {
            templateUrl: 'routesDemo/one'
        })
        .when('/routeTwo/:donuts', {
            templateUrl: function (params) { return '/routesDemo/two?donuts=' + params.donuts; }
        })
        .when('/routeThree', {
            templateUrl: 'routesDemo/three'
        });
}

و لینک مسیر 2 در صفحه Landing  به صورت زیر خواهد بود.

 <li><a href="/#/routeTwo/6">مسیر 2</a></li>

پس از اجرای آن و کلیک بر روی مسیر 2 نتیجه به صورت زیر خواهد بود.

مسیر 3 را برای ثبت نام قرار می دهیم. برای حفظ امنیت آن از  ASP.net authentication استفاده میکنیم.

صفت  Authorize را برای متد آن قرار می دهیم.

[Authorize]
public ActionResult Three()
{
    return View();
}

اگر برنامه را اجرا کنیم و بخواهیم به مسیر 3  دسترسی داشته باشیم در مرورگر خود با خطا مواجه خواهیم شد.

در اینجا  ASP.net اجازه دسترسی به این مسیر را به کاربر نمی دهد ، و سعی میکند کاربر را به صفحه ورود بفرستد. باید این خطا را با پاسخ  401  خودمان در  Angular عوض کنیم. ابتدا باید MVC را از هدایت کردن بر روی 401 متوقف کنیم. به  App_Start  رفته و در  Startup.Auth.cs به دنبال دستور زیر میگردیم.

LoginPath = new PathString("/Account/Login")

و آن را با کد زیر جابجا میکنیم.

LoginPath = new PathString(string.Empty)

حالا اگر بخواهیم به مسیر 3 دسترسی داشته باشیم، خطای زیر را در مرورگر مشاهده خواهیم کرد.

اگر بخواهیم با استفاده از interceptor آن را حل کنیم، یک دایرکتوری با نام Factories درون پوشه  Script ایجاد میکنیم و ScriptBundle  را درون  BundleConfig به صورت زیر آپدیت میکنیم .

bundles.Add(new ScriptBundle("~/bundles/AwesomeAngularMVCApp")
   .IncludeDirectory("~/Scripts/Controllers", "*.js")
   .IncludeDirectory("~/Scripts/Factories", "*.js")
   .Include("~/Scripts/AwesomeAngularMVCApp.js"));

فایل جاوا اسکریپت جدیدی را درون دایرکتوری  Factories با نام AuthHttpResponseInterceptor.js ایجاد میکنیم و کد های زیر را در آن قرار می دهیم.

var AuthHttpResponseInterceptor = function($q, $location) {
    return {
        response: function (response) {
            if (response.status === 401) {
                console.log("Response 401");
            }
            return response || $q.when(response);
        },
        responseError: function (rejection) {
            if (rejection.status === 401) {
                console.log("Response Error 401", rejection);
                $location.path('/login').search('returnUrl', $location.path());
            }
            return $q.reject(rejection);
        }
    }
}

AuthHttpResponseInterceptor.$inject = ['$q', '$location'];

اکنون باید آن را به angular  معرفی کنیم. بنابراین AwesomeAngularMVCApp.js  را به صورت زیر آپدیت میکنیم.

var AwesomeAngularMVCApp = angular.module('AwesomeAngularMVCApp', ['ngRoute']);

AwesomeAngularMVCApp.controller('LandingPageController', LandingPageController);
AwesomeAngularMVCApp.controller('LoginController', LoginController);

AwesomeAngularMVCApp.factory('AuthHttpResponseInterceptor', AuthHttpResponseInterceptor);

var configFunction = function ($routeProvider, $httpProvider) {
    $routeProvider.
        when('/routeOne', {
            templateUrl: 'routesDemo/one'
        })
        .when('/routeTwo/:donuts', {
            templateUrl: function (params) { return '/routesDemo/two?donuts=' + params.donuts; }
        })
        .when('/routeThree', {
            templateUrl: 'routesDemo/three'
        })
        .when('/login', {
            templateUrl: '/Account/Login',
            controller: LoginController
        });

    $httpProvider.interceptors.push('AuthHttpResponseInterceptor');
}
configFunction.$inject = ['$routeProvider', '$httpProvider'];

AwesomeAngularMVCApp.config(configFunction);

زمانی که احراز هویت با شکست مواجه شود مسیر یابی مناسبی در angular صورت خواهد گرفت. فقط نیاز داریم جایی برای هدایت شدن به آن داشته باشیم.

در ابتدای مقاله گفته شد که AccountController  حذف شود و اکنون می خواهیم یکی دیگر ایجاد کنیم. فایلی که شما پاک کردید نزدیک 500 خط کد بود و ما فقط بخشی از آن را نیاز داشتیم.

برای این کنترلر صفتی را به صورت زیر قرار می دهیم.

using System.Web.Mvc;

namespace AwesomeAngularMVCApp.Controllers
{
    [Authorize]
    public class AccountController : Controller
    {
        [AllowAnonymous]
        public ActionResult Login()
        {
            return View();
        }
    }
}

 View  آن را نیز مانند قبل ایجاد میکینم. این  View  به یک کنترلر  Angular نیاز دارد. پس فایل جاوا اسکریپتی با نام LoginController.js در پوشه Script -> Controller ایجاد میکینم و کدهای زیر را در آن قرار می دهیم.

var LoginController = function($scope, $routeParams) {
    $scope.loginForm = {
        emailAddress: '',
        password: '',
        rememberMe: false,
        returnUrl: $routeParams.returnUrl
    };

    $scope.login = function() {
        //todo
    }
}

LoginController.$inject = ['$scope', '$routeParams'];

مسیر در AwesomeAngularMVCApp.js باید برای معرفی شدن به angular و فراهم شدن کنترلر بالا برای  View آپدیت شود. و همچنین باید کنترلر را به ماژول برنامه خود معرفی کنیم.

var AwesomeAngularMVCApp = angular.module('AwesomeAngularMVCApp', ['ngRoute']);

AwesomeAngularMVCApp.controller('LandingPageController', LandingPageController);
AwesomeAngularMVCApp.controller('LoginController', LoginController);

var configFunction = function($routeProvider, $routeParams) {
    $routeProvider.
        when('/routeOne', {
            templateUrl: 'routesDemo/one'
        })
        .when('/routeTwo/:donuts', {
            templateUrl: function(params) { return '/routesDemo/two?donuts=' + params.donuts; }
        })
        .when('/routeThree', {
            templateUrl: 'routesDemo/three'
        })
        .when('/login?returnUrl', {
            templateUrl: 'Account/Login',
            controller: LoginController
        });
}
configFunction.$inject = ['$routeProvider'];

AwesomeAngularMVCApp.config(configFunction);

فرم ورود را در  View->Account ->Login.cshtml اضافه میکنیم.

<form ng-submit="login()">
    <label for="emailAddress">ایمیل</label>
    <input type="text" ng-model="loginForm.emailAddress" id="emailAddress" required/>
    <br/>
    <label for="password">کلمه عبور</label>
    <input type="password" id="password" ng-model="loginForm.password" required/>
    <br/>
    <label for="rememberMe">مرا بخاطر بسپار </label>
    <input type="checkbox" id="rememberMe" ng-model="loginForm.rememberMe" required/>

    <button type="submit">ورود</button>

</form>

اکنون اگر بخواهیم به مسیر 3 دسترسی داشته باشیم ، دو اتفاق خواهد افتاد .

1. یک پاسخ غیر مجاز بودن 401 دریافت میکنیم. که در کنسول مرورگر توسط انگولار گزارش می شود.

2. رهگیر یا interceptor ما را به  Login View  ایجاد شده راهنمایی میکند.

به یک فرم ثبت نام نیز برای کاربر جدید نیاز داریم. در کنترلر AccountController.cs متد زیر را اضافه میکنیم.

[AllowAnonymous]
public ActionResult Register()
{
    return View();
}

به یک کنترلر  Angular برای  Register Vuew  احتیاج داریم. یک فایل جاوا اسکریپت با نام RegisterController.js در Script ->Controllers ایجاد میکنیم و کدهای زیر را در آن قرار می دهیم.

var RegisterController = function($scope) {
    $scope.registerForm = {
        emailAddress: '',
        password: '',
        confirmPassword: ''
    };

    $scope.register = function() {
        //todo
    }
}

RegisterController.$inject = ['$scope'];

View آن را نیز ایجاد کرده و کدهای زیر را در آن قرار می دهیم.

<form ng-submit="register()">
    <label for="emailAddress">ایمیل</label>
    <input id="emailAddress" type="text" ng-model="registerForm.emailAddress" required/>
    <br/>

    <label for="password">کلمه عبور</label>
    <input id="password" type="password" ng-model="registerForm.password" required/>
    <br/>

    <label for="confirmPassword">تکرار کلمه عبور</label>
    <input id="confirmPassword" type="password" ng-model="registerForm.confirmPassword" required/>
    <br/>

    <button type="submit">ثبت نام</button>
</form>
<br />

اکنون باید AwesomeAngularMVCApp.js را با اطلاعات این کنترلر انگولار و مسیر جدید آپدیت میکنیم.

var AwesomeAngularMVCApp = angular.module('AwesomeAngularMVCApp', ['ngRoute']);

AwesomeAngularMVCApp.controller('LandingPageController', LandingPageController);
AwesomeAngularMVCApp.controller('LoginController', LoginController);
AwesomeAngularMVCApp.controller('RegisterController', RegisterController);

AwesomeAngularMVCApp.factory('AuthHttpResponseInterceptor', AuthHttpResponseInterceptor);

var configFunction = function ($routeProvider, $httpProvider) {
    $routeProvider.
        when('/routeOne', {
            templateUrl: 'routesDemo/one'
        })
        .when('/routeTwo/:donuts', {
            templateUrl: function (params) { return '/routesDemo/two?donuts=' + params.donuts; }
        })
        .when('/routeThree', {
            templateUrl: 'routesDemo/three'
        })
        .when('/login', {
            templateUrl: '/Account/Login',
            controller: LoginController
        })
        .when('/register', {
            templateUrl: '/Account/Register',
            controller: RegisterController
        });

    $httpProvider.interceptors.push('AuthHttpResponseInterceptor');
}
configFunction.$inject = ['$routeProvider', '$httpProvider'];

AwesomeAngularMVCApp.config(configFunction);

زمان آن رسیده که لینکهای  Login  و  Register  را در صفحه  landing اضافه کنیم.

<!DOCTYPE html>
<html ng-app="AwesomeAngularMVCApp" ng-controller="LandingPageController">
<head>
    <title ng-bind="models.helloAngular"></title>
</head>
<body>
    <h1>{{models.helloAngular}}</h1>

<ul>
    <li><a href="/#/routeOne">مسیر 1</a></li>
    <li><a href="/#/routeTwo/6">مسیر 2</a></li>
    <li><a href="/#/routeThree">مسیر 3</a></li>
</ul>
    <ul>
        <li><a href="/#/login">ورود</a></li>
        <li><a href="/#/register">ثبت نام</a></li>
    </ul>



<div ng-view></div>

    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-route.min.js"></script>
    @Scripts.Render("~/bundles/AwesomeAngularMVCApp")
</body>
</html>

AccountController هنوز چیزهایی کم دارد. بعضی وابستگی ها باید در آن رعایت کرد ، پس برای آن یک  ApplicationUserManager و یک  ApplicationSignInManager در نظر میگیریم که از طریق تزریق سازنده فراهم می شوند. همچنین باید متدهای ورود و ثبت نام را اضافه کنیم.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using AwesomeAngularMVCApp.Models;
using Microsoft.AspNet.Identity.Owin;

namespace AwesomeAngularMVCApp.Controllers
{
    [Authorize]
    public class AccountController : Controller
    {
        private ApplicationUserManager _userManager;
        private ApplicationSignInManager _signInManager;

        public AccountController() { }

        public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
        {
            UserManager = userManager;
            SignInManager = signInManager;
        }

        public ApplicationUserManager UserManager
        {
            get { return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
            private set { _userManager = value; }
        }

        public ApplicationSignInManager SignInManager
        {
            get { return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); }
            private set { _signInManager = value; }
        }

        [AllowAnonymous]
        public ActionResult Login()
        {
            return View();
        }

        [AllowAnonymous]
        public ActionResult Register()
        {
            return View();
        }
        [HttpPost]
        [AllowAnonymous]
        public async Task<bool> Login(LoginViewModel model)
        {
            var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false);
            switch (result)
            {
                case SignInStatus.Success:
                    return true;
                default:
                    ModelState.AddModelError("", "دوباره تلاش کنید");
                    return false;
            }
        }

        [HttpPost]
        [AllowAnonymous]
        public async Task<bool> Register(RegisterViewModel model)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (!result.Succeeded) return false;
            await SignInManager.SignInAsync(user, false, false);
            return true;
        }
    }
}

قدم بعدی پر کردن توابع  register  و Login در کنترلرهای  AngularJS مربوطه است. نمیخواهیم این منطق را در کنترلرهای خود قرار دهیم. روش بهتر برای این کار ایجاد یک  Angular factory است. یک  LoginFactory.js در  Script->Factories ایجاد میکنیم و کدهای زیر را در آن قرار می دهیم.

var LoginFactory = function ($http, $q) {
    return function (emailAddress, password, rememberMe) {

        var deferredObject = $q.defer();

        $http.post(
            '/Account/Login', {
                Email: emailAddress,
                Password: password,
                RememberMe: rememberMe
            }
        ).
        success(function (data) {
            if (data == "True") {
                deferredObject.resolve({ success: true });
            } else {
                deferredObject.resolve({ success: false });
            }
        }).
        error(function () {
            deferredObject.resolve({ success: false });
        });

        return deferredObject.promise;
    }
}

LoginFactory.$inject = ['$http', '$q'];

این factory  را به برنامه انگولار به صورت زیر معرفی میکنیم.

AwesomeAngularMVCApp.factory('LoginFactory', LoginFactory);

این  factory را به  LoginController نیز تزریق میکنیم و تابع آن را هنگامی که تابع  Login  کنترلر درخواست شد فراخوانی میکنیم.

var LoginController = function ($scope, $routeParams, $location, LoginFactory) {
    $scope.loginForm = {
        emailAddress: '',
        password: '',
        rememberMe: false,
        returnUrl: $routeParams.returnUrl,
        loginFailure: false
    };

    $scope.login = function () {
        var result = LoginFactory($scope.loginForm.emailAddress, $scope.loginForm.password, $scope.loginForm.rememberMe);
        result.then(function(result) {
            if (result.success) {
                if ($scope.loginForm.returnUrl !== undefined) {
                    $location.path('/routeOne');
                } else {
                    $location.path($scope.loginForm.returnUrl);
                }
            } else {
                $scope.loginForm.loginFailure = true;
            }
        });
    }
}

LoginController.$inject = ['$scope', '$routeParams', '$location', 'LoginFactory'];

همچنین یک تغییر کوچک در LoginView  لازم داریم.

<form ng-submit="login()">
    <label for="emailAddress">ایمیل</label>
    <input type="text" ng-model="loginForm.emailAddress" id="emailAddress" required/>
    <br/>
    <label for="password">کلمه عبور</label>
    <input type="password" id="password" ng-model="loginForm.password" required/>
    <br/>
    <label for="rememberMe">مرا بخاطر بسپار </label>
    <input type="checkbox" id="rememberMe" ng-model="loginForm.rememberMe" required/>

    <button type="submit">ورود</button>

</form>
<br/>
<div ng-if="loginForm.loginFailure">
     ورود ناموفق !
</div>

برنامه را اجرا کرده و هنگام درخواست ورود نتیجه به صورت زیر می باشد.

" ورود ناموفق " به این دلیل است که هنوز کاربری نداریم. به سراغ factory ثبت نام می رویم. RegistrationFactory.js را در  Factories اضافه کرده و کدهای زیر را در آن قرار می دهیم.

var RegistrationFactory = function ($http, $q) {
    return function (emailAddress, password, confirmPassword) {

        var deferredObject = $q.defer();

        $http.post(
            '/Account/Register', {
                Email: emailAddress,
                Password: password,
                ConfirmPassword: confirmPassword
            }
        ).
        success(function (data) {
            if (data == "True") {
                deferredObject.resolve({ success: true });
            } else {
                deferredObject.resolve({ success: false });
            }
        }).
        error(function () {
            deferredObject.resolve({ success: false });
        });

        return deferredObject.promise;
    }
}

RegistrationFactory.$inject = ['$http', '$q'];

این factory  جدید را نیز به  Angular  معرفی میکنیم.

AwesomeAngularMVCApp.factory('RegistrationFactory', RegistrationFactory);

سپس آن را در RegisterController تزریق کرده و تابع آن را فراخوانی میکنیم.

var RegisterController = function ($scope, $location, RegistrationFactory) {
    $scope.registerForm = {
        emailAddress: '',
        password: '',
        confirmPassword: '',
        registrationFailure: false
    };

    $scope.register = function () {
        var result = RegistrationFactory($scope.registerForm.emailAddress, $scope.registerForm.password, $scope.registerForm.confirmPassword);
        result.then(function (result) {
            if (result.success) {
                $location.path('/routeOne');
            } else {
                $scope.registerForm.registrationFailure = true;
            }
        });
    }
}

RegisterController.$inject = ['$scope', '$location', 'RegistrationFactory'];

اکنون می توانیم برنامه را اجرا کرده و به عنوان یک کاربر ثبت نام کنیم و مسیر 3 را ببینیم.

آموزش angular

فایل های ضمیمه

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

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

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

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