من اینجا هستم تا بحث پیرامون AngularJS 2.0 را ادامه دهم . در مقاله قبلی خود، قبلاً در مورد اتصال فرم مبتنی بر مدل در Angular 2.0 بحث کردم. اکنون در این مقاله در مورد ماژول http یا نحوه فراخوانی APIهای خارجی در Angular 2.0 بحث خواهیم کرد. در صورتی که نگاهی به مقالات قبلی این مجموعه نداشتید، به لینک های ذکر شده در زیر مراجعه کنید.
- AngularJS 2.0 از ابتدا معرفی AngularJS 2.0 (روز اول)
- کامپوننت AngularJS 2.0 از ابتدا (روز 2)
- AngularJS 2.0 از ابتدای اتصال داده ها (روز 3)
- AngularJS 2.0 از ابتدا اتصال داده های ورودی (روز 4)
- AngularJS 2.0 از ابتدا - Output Property Binding (روز 5)
- AngularJS 2.0 از ابتدا - دستورالعمل ویژگی (روز 6)
- AngularJS 2.0 از ابتدا - دستورالعمل های ساختاری (روز 7)
- AngularJs 2.0 از ابتدا - Pipes (روز 8)
- AngularJS 2.0 از ابتدا - Viewchild (روز نهم)
- AngularJS 2.0 از ابتدا - Dynamic Grid (روز 10)
- AngularJS 2.0 از ابتدا - سرویس (روز 11)
- AngularJs 2.0 از ابتدا - ngContent (روز دوازدهم)
- AngularJS 2.0 از ابتدا - Route Part I (روز سیزدهم)
- AngularJs 2.0 از ابتدا - Route Part 2 (روز چهاردهم)
- AngularJs 2.0 از ابتدا - ngForm قسمت 1 (روز 15)
- AngularJs 2.0 از ابتدا - ngForm قسمت 2 (روز 16)
Angular 2 بسیاری از مفاهیم نوآورانه مانند بهبود عملکرد، مسیریابی اجزا، تزریق وابستگی تیز (DI)، بارگذاری تنبل، قالب غیر همگام، توسعه موبایل با Native Script را معرفی می کند. همه با یک ابزار قوی و پشتیبانی تست عالی مرتبط هستند. ایجاد درخواستهای HTTP در برنامههای Angular 2 تا حدودی با آنچه که ما از Angular 1.x به آن عادت کردهایم متفاوت به نظر میرسد، یک تفاوت اصلی این است که Http Angular 2 قابل مشاهدهها را برمیگرداند .
برای ما کاملا واضح است که Angular 2.0 همیشه در مقایسه با Angular 1.x متفاوت به نظر می رسد. در صورت فراخوانی Http API، همان سناریو رخ داد. سرویس $http، که Angular 1.x در اختیار ما قرار می دهد، در بیشتر موارد بسیار خوب عمل می کند. Angular 2.0 Http ما را ملزم می کند که مفاهیم یا مکانیسم جدیدی از جمله نحوه کار با مشاهده پذیرها را بیاموزیم.
Reactive Extensions for JavaScript (RxJS) یک کتابخانه جریان های واکنشی است که به شما امکان می دهد با Observables کار کنید. RxJS Observables ، Operators و Scheduler ها را ترکیب می کند، بنابراین ما می توانیم در جریان ها مشترک شویم و با استفاده از عملیات ترکیبی به تغییرات واکنش نشان دهیم.
تفاوت بین Angular 1.x $http و Angular 2 Http
فراخوانی Http API Angular 2 دوباره روشی نسبتاً ساده برای رسیدگی به درخواستها ارائه میکند. برای شروع، HTTP در Angular 2 به طور پیشفرض، مشاهدهپذیرها را از طریق RxJS برمیگرداند ، در حالی که $http در Angular 1.x Promises را برمیگرداند. استفاده از جریانهای قابل مشاهده، هنگام رسیدگی به پاسخهایی که از درخواستهای HTTP به میان میآید، به ما منفعت انعطافپذیری بیشتری میدهد. به عنوان مثال، ما این پتانسیل را داریم که از اپراتورهای مفید RxJS مانند تلاش مجدد استفاده کنیم، به طوری که یک درخواست HTTP ناموفق به طور خودکار دوباره ارسال می شود، که برای مواردی مفید است که کاربران ارتباطات شبکه ضعیف یا متناوب دارند.
در Angular 2، Http به عنوان یک کلاس تزریقی از angular2/http قابل دسترسی است و مانند کلاس های دیگر، زمانی که می خواهیم از آن در اجزای خود استفاده کنیم، آن را وارد می کنیم. Angular 2 همچنین دارای مجموعه ای از ارائه دهندگان تزریقی برای Http است که از طریق HTTP_PROVIDERS وارد می شوند. با این ها، ما ارائه دهندگانی مانند RequestOptions و ResponseOptions را دریافت می کنیم که به ما امکان می دهد درخواست ها و پاسخ ها را با گسترش کلاس پایه برای هر کدام تغییر دهیم. در Angular 1.x، ما این کار را با ارائه یک تابع transformRequest یا transformResponse به گزینه های $http خود انجام می دهیم.
مشاهده پذیرها در مقابل وعده ها
وقتی با Http استفاده میشود، هر دو پیادهسازی یک API آسان برای رسیدگی به درخواستها ارائه میکنند، اما برخی تفاوتهای کلیدی وجود دارد که باعث میشود Observables; یک جایگزین برتر
- Promises فقط یک مقدار را می پذیرد مگر اینکه چندین Promises بنویسیم (مثلاً: $q.all ).
- وعده ها لغو نمی شود
ماژول http Angular 2 @angular/http یک سرویس Http را نشان می دهد که برنامه ما می تواند از آن برای دسترسی به خدمات وب از طریق HTTP استفاده کند. ما از این ابزار در سرویس PeopleService خود استفاده خواهیم کرد. ما با وارد کردن آن با هم تمام انواع مربوط به انجام درخواست http را شروع می کنیم:
- import { Http, Response } from '@angular/http';
- import { Observable } from 'rxjs/Rx';
اینها همه انواع و روش های مورد نیاز برای ایجاد و رسیدگی به درخواست HTTP به یک سرویس وب هستند:
- Http
سرویس Angular 2 http که API را برای ایجاد درخواست های HTTP با روش های مربوط به افعال HTTP مانند get، post، put و غیره ارائه می دهد.
- پاسخی
که نشان دهنده پاسخی از یک سرویس HTTP است و از مشخصات واکشی API پیروی می کند
- قابل مشاهده
است که الگوی غیر همگام مورد استفاده در Angular 2 است. مفهوم مشاهده پذیر از الگوی طراحی ناظر به عنوان یک شی می آید که به یک طرف علاقه مند از ناظران هنگام وقوع اتفاق جالبی اطلاع می دهد. در RxJها تعمیم داده شده است که دنبالههایی از دادهها یا رویدادها را مدیریت کنید، برای ترکیب کردن با سایر قابل مشاهدهها و ارائه بسیاری از توابع کاربردی معروف به عملگرها که به شما امکان میدهد به چیزهای شگفتانگیزی دست پیدا کنید.
Angular با کتابخانه HTTP خود ارائه می شود که می توانیم از آن برای فراخوانی API های خارجی استفاده کنیم.
هنگامی که ما با یک سرور خارجی تماس می گیریم، می خواهیم کاربر همچنان بتواند با صفحه تعامل داشته باشد، یعنی تا زمانی که درخواست HTTP از سرور خارجی برگردد، نمی خواهیم صفحه ما مسدود شود. برای دستیابی به این اثر، درخواست های HTTP ما ناهمزمان هستند.
برخورد با کد ناهمزمان، از نظر تاریخی، دشوارتر از برخورد با کد همزمان است. در جاوا اسکریپت، به طور کلی سه رویکرد برای مقابله با کدهای ناهمزمان وجود دارد، یعنی.
- تماس های تلفنی
- وعده ها
- قابل مشاهده
اکنون در این مقاله نحوه دسترسی یا فراخوانی روش GET کنترلر Web API برای واکشی داده ها را نشان خواهیم داد.
برای این کار ابتدا باید پروژه دیگری از نوع ASP.NET Web Application اضافه کنیم و گزینه Web API را از کادر محاوره ای جدید انتخاب کنیم. پس از ایجاد پروژه، فایل های زیر را اضافه کنید.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- namespace SampleAPI.Models.Sample
- {
- public class Employee
- {
- public int Id { get; set; }
- public string Code { get; set; }
- public string Name { get; set; }
- public DateTime DOB { get; set; }
- public DateTime DOJ { get; set; }
- public string Department { get; set; }
- public string Designation { get; set; }
- public double Salary { get; set; }
- }
- }
- using SampleAPI.Models.Sample;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Web.Http;
- using System.Web.Http.Description;
- namespace SampleAPI.Controllers.Sample
- {
- public class EmployeeController : ApiController
- {
- public EmployeeController()
- {
- }
- [ResponseType(typeof(Employee))]
- [HttpGet]
- [Route("Employee/GetEmployee")]
- public IHttpActionResult GetEmployee()
- {
- return Ok(this.FetchEmployee());
- }
- private List<Employee> FetchEmployee()
- {
- List<Employee> lstData = new List<Employee>();
- Employee objEmp = new Employee() { };
- objEmp.Id = 1;
- objEmp.Code = "A001";
- objEmp.Name = "RABIN";
- objEmp.DOB = Convert.ToDateTime("10-06-1980");
- objEmp.DOJ = Convert.ToDateTime("01-09-2006");
- objEmp.Department = "ACCOUNTS";
- objEmp.Designation = "CLERK";
- objEmp.Salary = 15000.00;
- lstData.Add(objEmp);
- objEmp = new Employee() { };
- objEmp.Id = 2;
- objEmp.Code = "A002";
- objEmp.Name = "SUJIT";
- objEmp.DOB = Convert.ToDateTime("12-22-1986");
- objEmp.DOJ = Convert.ToDateTime("04-15-2010");
- objEmp.Department = "SALES";
- objEmp.Designation = "MANAGER";
- objEmp.Salary = 35000.00;
- lstData.Add(objEmp);
- objEmp = new Employee() { };
- objEmp.Id = 3;
- objEmp.Code = "A003";
- objEmp.Name = "KAMALESH";
- objEmp.DOB = Convert.ToDateTime("03-22-1982");
- objEmp.DOJ = Convert.ToDateTime("07-15-2006");
- objEmp.Department = "ACCOUNTS";
- objEmp.Designation = "CLERK";
- objEmp.Salary = 16000.00;
- lstData.Add(objEmp);
- return lstData;
- }
- }
- }
اکنون میتوانیم پروژه API را اجرا کنیم و از مرورگر به متد GetEmployee دسترسی پیدا کنیم تا دادهها را واکشی کنیم، اما وقتی میخواهیم به همان متد Web API از پروژه Angular 2 خود دسترسی پیدا کنیم، خطایی به نام خطای منشأ متقاطع رخ میدهد. برای حل این خطا باید Microsoft ASP.NET Cors را در پروژه Web API از NuGet Manager نصب کنیم، همانطور که در زیر نشان داده شده است.
اکنون فایل WebAPIConfig.cs پروژه Web AP را مطابق شکل زیر تغییر دهید.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net.Http;
- using System.Web.Http;
- using Microsoft.Owin.Security.OAuth;
- using Newtonsoft.Json.Serialization;
- using System.Web.Http.Cors;
- namespace SampleAPI
- {
- public static class WebApiConfig
- {
- public static void Register(HttpConfiguration config)
- {
- // Web API configuration and services
- // Configure Web API to use only bearer token authentication.
- config.SuppressDefaultHostAuthentication();
- config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
- // Web API routes
- config.MapHttpAttributeRoutes();
- var cors = new EnableCorsAttribute("*", "*", "*");
- config.EnableCors(cors);
- config.Routes.MapHttpRoute(
- name: "DefaultApi",
- routeTemplate: "api/{controller}/{id}",
- defaults: new { id = RouteParameter.Optional }
- );
- }
- }
- }
حالا به پروژه Angular 2 برگردید و فایل های زیر را با کد ایجاد کنید.
app.component.homepage.html
- <div>
- <h3>HTTP Module Sample - Get Data</h3>
- <div class="panel panel-default">
- <div class="panel-body">
- <table class="table table-striped table-bordered">
- <thead>
- <tr>
- <th>Srl No</th>
- <th>Alias</th>
- <th>Employee Name</th>
- <th>Date of Birth</th>
- <th>Join Date</th>
- <th>Department</th>
- <th>Designation</th>
- <th>Salary</th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let item of data">
- <td>{{item.Id}}</td>
- <td>{{item.Code}}</td>
- <td>{{item.Name}}</td>
- <td>{{item.DOB | date :'shortDate'}}</td>
- <td>{{item.DOJ | date :'mediumDate'}}</td>
- <td>{{item.Department}}</td>
- <td>{{item.Designation}}</td>
- <td>{{item.Salary |currency:'INR':true}}</td>
- </tr>
- </tbody>
- </table>
- <p>
- <button class="btn btn-primary" (click)="loadData()">
- Load Data
- </button>
- </p>
- </div>
- </div>
- </div>
app.component.homepage.ts
- import { Component, OnInit, ViewChild } from '@angular/core';
- import { Http, Response } from '@angular/http';
- import 'rxjs/Rx';
- @Component({
- moduleId: module.id,
- selector: 'home-page',
- templateUrl: 'app.component.homepage.html'
- })
- export class HomePageComponent implements OnInit {
- private data: Array<any> = [];
- constructor(private http: Http) {
- }
- ngOnInit(): void {
- }
- private loadData(): void {
- debugger;
- let self = this;
- this.http.request('http://localhost:5201/employee/getemployee')
- .subscribe((res: Response) => {
- self.data = res.json();
- });
- }
- }
app.module.ts
- import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
- import { BrowserModule } from '@angular/platform-browser';
- import { ReactiveFormsModule } from "@angular/forms";
- import { HttpModule } from '@angular/http';
- import { HomePageComponent } from './src/app.component.homepage';
- @NgModule({
- imports: [BrowserModule, ReactiveFormsModule, HttpModule],
- declarations: [HomePageComponent],
- bootstrap: [HomePageComponent]
- })
- export class AppModule { }
main.ts
- import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
- import { AppModule } from './app.module';
- const platform = platformBrowserDynamic();
- platform.bootstrapModule(AppModule);
index.html
- <!DOCTYPE html>
- <html>
- <head>
- <title>Angular2 - HTTP Module (GET) </title>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link href="../resources/style/bootstrap.css" rel="stylesheet" />
- <link href="../resources/style/style1.css" rel="stylesheet" />
- <!-- Polyfill(s) for older browsers -->
- <script src="../resources/js/jquery-2.1.1.js"></script>
- <script src="../resources/js/bootstrap.js"></script>
- <script src="../node_modules/core-js/client/shim.min.js"></script>
- <script src="../node_modules/zone.js/dist/zone.js"></script>
- <script src="../node_modules/reflect-metadata/Reflect.js"></script>
- <script src="../node_modules/systemjs/dist/system.src.js"></script>
- <script src="../systemjs.config.js"></script>
- <script>
- System.import('app').catch(function (err) { console.error(err); });
- </script>
- <!-- Set the base href, demo only! In your app: <base href="/"> -->
- <script>document.write('<base href="' + document.location + '" />');</script>
- </head>
- <body>
- <home-page>Loading</home-page>
- </body>
- </html>
حالا کد را اجرا کنید و خروجی در زیر نشان داده شده است.