Series Angular2 – WebApi 4: Tạo Client bằng Angular2 Method Post, Put

  • Tiếp theo mình sẽ hướng dẫn các bạn phần thêm môt class sử dụng reactiveForm
  • Ở phía trên class.service.ts chúng ta đã có method post rồi nên giờ chúng ta chỉ cần thêm function gọi method đó ở trong clas.component.ts và sửa view html thôi

Class.component.ts

import { Component, OnInit } from ‘@angular/core’;

import { ClassService } from ‘./class.service’;

//import lb FormReactive

import { FormGroup, FormBuilder, Validators, FormControl } from ‘@angular/forms’;

@Component({

selector: ‘class-component’,

templateUrl: ‘./class.component.html’,

styleUrls: [‘./class.component.css’]

})

export class ClassComponent implements OnInit {

private classes: Class[];

private errorMessage: string;

//create FormGroup

private classForm: FormGroup;

constructor(

private classService: ClassService,

private fb: FormBuilder

) {

this.createForm();

}

ngOnInit() {

this.getClass();

}

getClass() {

this.classService.getclasses()

.subscribe(

classes => this.classes = classes,

error => this.errorMessage = <any>error);

}

//create class

createForm() {

this.classForm = this.fb.group({

ClassName: new FormControl()

})

}

createClass(){

var newclass = this.classForm.value;

this.classService.create(newclass).subscribe(

class1  => this.classes.push(class1),

error =>  this.errorMessage = <any>error);

}

}

Các bạn để ý các phần mình comment

  • component.html

<ul>

<li *ngFor=”let class of classes”>{{class.ClassName}}</li>

</ul>

<form[formGroup]=”classForm” (ngSubmit)=”createClass()” novalidate>

<input type=”text” formControlName=”ClassName”>

<button type=”submit”>Submit</button>

</form>

Vì sử dụng reactive form nên có add thêm Module, các bạn mở app.module.ts và bổ sung import ReactiveFormModule vào nhé

import{ BrowserModule } from ‘@angular/platform-browser’;

import{ NgModule } from ‘@angular/core’;

//add ReactiveFormsModule

import{ FormsModule, ReactiveFormsModule } from ‘@angular/forms’;

import{ HttpModule } from ‘@angular/http’;

import{ AppComponent } from ‘./app.component’;

import{ ClassComponent } from ‘./class/class.component’;

import{ ClassService } from ‘./class/class.service’;

@NgModule({

declarations: [

AppComponent,

ClassComponent

],

imports: [

BrowserModule,

ReactiveFormsModule,

FormsModule,

HttpModule

],

providers: [ClassService],

bootstrap: [AppComponent]

})

exportclass AppModule { }

  • Ok xong quay lại giao diện và thêm thử class vào thôi
  • Tiếp theo Edit chúng ta lại sửa code một chút
  • service.ts bổ sung method edit

edit(id: any, name: Class):Observable<Class> {

let headers = new Headers({ ‘Content-Type’: ‘application/json’ });

let options = new RequestOptions({ headers: headers });

return this.http.put(this.classesUrl + ‘/’ + id, name, options)

.map(this.extractData)

.catch(this.handleError);

}

component.ts

import{ Component, OnInit } from ‘@angular/core’;

import{ ClassService } from ‘./class.service’;

//import lb FormReactive

import{ FormGroup, FormBuilder, Validators, FormControl } from ‘@angular/forms’;

@Component({

selector: ‘class-component’,

templateUrl: ‘./class.component.html’,

styleUrls: [‘./class.component.css’]

})

exportclass ClassComponent implements OnInit {

private classes: Class[];

private errorMessage: string;

//create FormGroup

private classForm: FormGroup;

private objClass: Class;

private classId: any;

constructor(

private classService: ClassService,

private fb: FormBuilder

) {

this.objClass = new Class();

this.createForm(this.objClass);

}

ngOnInit() {

this.getClass();

}

getClass() {

this.classService.getclasses()

.subscribe(

classes => this.classes = classes,

error => this.errorMessage = <any>error);

}

//create class

createForm(cl: Class) {

this.classForm = this.fb.group({

ClassName: new FormControl(cl.ClassName)

})

}

onsubmit(){

var newclass = this.classForm.value;

if(this.classId){

this.objClass = newclass;

this.objClass.ClassID = this.classId;

this.classService.edit(this.classId, this.objClass).subscribe(

obj=>{

this.getClass();

}

)

}else{

this.classService.create(newclass).subscribe(

class1 => this.classes.push(class1),

error => this.errorMessage = <any>error);

}

}

editClass(id: any) {

this.classId = id;

//find object need edit

this.objClass = this.classes.filter(item => item.ClassID == id)[0];

//view objet to textbox

this.createForm(this.objClass);

}

}

exportclass Class {

public ClassID: number;

public ClassName: string;

}

  • Vì sử dụng chung 1 form nên chúng ta sẽ viết chung method onSubmit() để dùng gọi cả 2 method post và put, lúc nào gọi post thì chúng ta để ý khi post thì ClassID = null, còn put(tức edit) thì phải cần ClassId để edit nên chúng ta sẽ dùng ClassID để phân biệt

if(this.classId){

this.objClass = newclass;

this.objClass.ClassID = this.classId;

this.classService.edit(this.classId, this.objClass).subscribe(

obj=>{

this.getClass();

}

)

}else{

this.classService.create(newclass).subscribe(

class1 => this.classes.push(class1),

error => this.errorMessage = <any>error);

}

  • classId có đc bằng cách khi click vào button Edit sẽ gửi Id xuống component

<li*ngFor=”let class of classes”>{{class.ClassName}} <button type=”button” (click)=”editClass(class.ClassID)”>Edit</button></li>

Edit function

editClass(id: any) {

this.classId = id;

//find object need edit

this.objClass = this.classes.filter(item => item.ClassID == id)[0];

//view objet to textbox

this.createForm(this.objClass);

}

  • File class.component.html

<ul>

<li *ngFor=”let class of classes”>{{class.ClassName}} <button type=”button” (click)=”editClass(class.ClassID)”>Edit</button></li>

</ul>

<buttontype=”button” (click)=”classId=null”>Create</button>

<form[formGroup]=”classForm” (ngSubmit)=”onsubmit()” novalidate>

<input type=”text” formControlName=”ClassName”>

<button type=”submit”>Submit</button>

</form>

  • Như bạn nhìn thấy mình đã sửa file createForm hơi khác với lúc create

createForm(cl: Class) {

this.classForm = this.fb.group({

ClassName: new FormControl(cl.ClassName)

})

}

Bên trong có truyền vào cl.ClassName, cái này đc dùng lúc binding dữ liệu Edit lên ô text

  • Ok xong rồi test thử thôi

  • Khi click vào button Edit, dữ liệu sẽ binding xuống ô text và sửa
  • Mình có tạo thêm button Create để gán lại ClassId về null, chuyển từ edit sang create

link source cho ai cần nhé: DownLoad

Series Angular2 – WebApi 3: Tạo Client bằng Angular2

  • Phần tiếp theo chúng ta sẽ tạo client Angular2
  • Ở đây mình sẽ tạo nhanh bằng cách sử dụng Angular-Cli (Angular Class Libary)
  • Đầu tiền chúng ta sẽ setup Angular-cli: mở giao diện cmd ra và gõ “npm install –g @angular/cli”
  • Chọn vị trí trên ổ đĩa mà chúng ta muốn để Client Angular2, mở giao diện cmd tại vị trí đó và gõ “ng new angular2-api-demo” với “angular2-api-demo” là tên thư mục thôi gõ gì cũng đc
  • Đợi một khoảng thời gian cho nó tự động setup các thư viện hơi lâu đấy chờ thôi, sau đó vào thư mục “angular2-api-demo” lại mở cmd và gõ “ng serve”
  • Để cho nhanh các bạn có thể copy đoạn code xong và paste thẳng vào cmd (ví trí đã chọn để folder Angular2-client)

npm install –g @angular/cli

ng new angular2-api-demo

cd  angular2-api-demo

ng serve

(giải thích một chút về cái –g, -g ở đây là –global tức là chung khi cài cái này thì nó sẽ đc lưu tại chỗ khác trên ổ C thường là trong  C/User… và nó sẽ được dùng chung cho các app sử dụng, còn nếu không có –g thì nó chỉ đc install trong app đó thôi, muốn app khác dùng phải cài lại)

Giao diện khi nó setup (đừng tắt đi nhá)

Giao diện khi chạy xong

Xong các bạn vào địa chỉ : http://localhost:4200/ nếu thấy chữ App work!! Là thành công, đã xong việc chạy app lần đầu tiên, bây giờ thì thử code thôi.

  • Tiếp theo các bạn mở thư mục angular2-api-demo bằng IDE để code, mình hay sử dụng Visual Studio Code dùng cũng khá hay các bạn có thể lên google tìm tải hoàn toàn miễn phí. Giao diện mở lên như sau:

  • Để tiếp tục series các bạn phải có một chút kiến thức về Angular 2, các bạn có thể lên trang chủ https://angular.io tìm hiểu, làm vài ví dụ để hiểu rõ hơi về các hoạt động nhé. Mình sẽ nói qua lại một chút, bạn nào hiểu nhanh thì sẽ hiểu được luôn
  • Angular2 là một framework do google viết, mới được release vào cuối năm 2016(khá mới phải không) nhưng được khá đông đảo người dùng ưu thích.
  • Angular 2 là một framework với sự sắp xếp hợp lý hơn cho phép lập trình viên tập trung vào việc tạo lên các class JavaScript đơn giản. Views và các controllers sẽ được thay thế bởi Components, thứ mà có thể mô tả là một sự tinh chế mới của directives.
  • Quan sát ở trên các bạn thấy các file code được nằm trong folder app: gồm các file component.ts, .html, .css, spect.ts(file test), module.ts (để khai báo các component và inject các directive, service…)
  • Các bạn thấy @Component có khai báo đường dẫn file Html và css đây là template của component , phía dưới là file class thực hiện các tính toán, rồi hiển thị lên html
  • Bây giờ chúng ta thử tạo 1 hiển thị list các Classes lên html nhé:
  • Tạo một thư mục class trong app và tạo 4 file:

class.component.css

class.component.html

class.component.ts

class.service.ts

  • Đầu tiên là tạo service để request và nhận response từ web api service.ts

// Observable Version

import{ Injectable }              from ‘@angular/core’;

import{ Http, Response }          from ‘@angular/http’;

import{ Headers, RequestOptions } from ‘@angular/http’;

import{ Observable } from ‘rxjs/Observable’;

import’rxjs/add/operator/catch’;

import’rxjs/add/operator/map’;

import{ Class } from ‘./class.component’;

@Injectable()

exportclass ClassService {

private classesUrl = ‘http://localhost:5392/api/ClassModels/&#8217;  ;  // URL to web API

constructor (private http: Http) {}

getclasses(): Observable<Class[]> {

return this.http.get(this.classesUrl)

.map(this.extractData)

.catch(this.handleError);

}

create(name: Class):Observable<Class> {

let headers = new Headers({ ‘Content-Type’: ‘application/json’ });

let options = new RequestOptions({ headers: headers });

return this.http.post(this.classesUrl, name, options)

.map(this.extractData)

.catch(this.handleError);

}

private extractData(res: Response) {

let body = res.json();

return body || { };

}

private handleError (error: Response | any) {

// In a real world app, you might use a remote logging infrastructure

let errMsg: string;

if (error instanceof Response) {

const body = error.json() || ”;

const err = body.error || JSON.stringify(body);

errMsg = `${error.status} – ${error.statusText || ”} ${err}`;

} else {

errMsg = error.message ? error.message : error.toString();

}

console.error(errMsg);

return Observable.throw(errMsg);

}

}

Phía trên các bạn thấy

import{ Class } from ‘./class.component’;

cái này là Model tạo dưới client đáng ra nên tạo thành class riêng nhưng nó ko có nhiều trường nên mình viết luôn trong class.component.ts

component.ts

import{ Component, OnInit } from ‘@angular/core’;

import{ ClassService } from ‘./class.service’

@Component({

selector: ‘class-component’,

templateUrl: ‘./class.component.html’,

styleUrls: [‘./class.component.css’]

})

exportclass ClassComponent implements OnInit {

private classes: Class[];

private errorMessage: string;

constructor(private classService: ClassService) { }

ngOnInit(){

this.getClass();

}

getClass() {

this.classService.getclasses()

.subscribe(

classes => this.classes = classes ,

error => this.errorMessage = <any>error);

}

}

exportclass Class {

constructor(

public ClassID: number,

public ClassName: string) { }

}

  • component.html

<ul>

<li *ngFor=”let class of classes”>{{class.ClassName}}</li>

</ul>

  • Ok giờ các bạn refresh lại web localhost:4200 xem thế nào nhé, nêu không thấy hiển thị class và f12 lên các bạn thấy có lỗi này:

Đừng lo đây là lỗi Origin tức là web api không cho phép một domain khác gọi đến api của nó, vì đây là ăn cắp tài nguyên, của nó chỉ có thể cho domain của nó sử dụng. theo lý thuyết là chúng ta đang gọi api localhost:5392 (cái này theo máy mình nhé) từ domain localhost:4200. Để giải quyết vấn đề này các bạn install thêm package Microsoft.AspNet.WebApi.Cors

Lại mở package Manager Console lên và gõ

Install-Package Microsoft.AspNet.Cors

Sau đo thêm đoạn code sau:

  • Thêm vào ClassModelsController

[EnableCors(origins: ‘http://localhost:4200&#8217;, header: ‘*’, methods: ‘*’)]

  • Thêm vào App_Start/WebapiConfig

  • Ok run lại api server và refesh lại localhost:4200 xem nào

  • Chúng ta đã hiển thị đc 2 class rồi (nhớ là phải demo dữ liệu vào db không có thì sao mà hiển thị đc)

Series Angular2 – WebApi 2: Tạo ASP.NET Web api

  • Tạo cây project Web api như sau: Đặt tên là DemoWebApiAngular2

  • Chúng ta sẽ viết 1 website đơn giản để nhập vào Class và Student của Class đó: Vào DemoWebApiAngular2/Models tạo 2 class: ClassModel, StudentModel:public class ClassModel

    {

    public int ClassID { get; set; }

    public string ClassName { get; set; }

    }

    public class StudentModel

    {

    public int StudentID { get; set; }

    public string StudentName { get; set; }

    public DateTime? BirthDate { get; set; }

    public int ClassID { get; set; }

    [ForeignKey(“ClassID”)]

    public virtual ClassModel Class { get; set; }

    }

  • Tiếp theo sửa một chút code trong file DemoWebApiAngular2/Models/ cs bạn nào biết một chút về asp.net code first rồi thì sẽ dễ hơn nhiều, còn không thì chú ý nghe mình nói tiếp. Bạn nhìn trong file đó có class: ApplicationDbContext sửa nội dung trong class đó lại như sau:

    public ApplicationDbContext()

: base(“DemoStudentConnection”, throwIfV1Schema: false)

{

}

public DbSet<ClassModel> Classes { get; set; }

public DbSet<StudentModel> Students { get; set; }

public static ApplicationDbContext Create()

{

return new ApplicationDbContext();

}

protected override void OnModelCreating(DbModelBuilder modelBuilder)

{

base.OnModelCreating(modelBuilder);

 

modelBuilder.Entity<ClassModel>().HasKey(x => x.ClassID);

modelBuilder.Entity<StudentModel>().HasKey(x => x.StudentID);

}

(trong đó “DemoStudentConnection” là tên connectionString chúng ta sẽ sửa )

  • Mở Web.cofig tìm trong thẻ <connectionString> xóa nội dung trong thẻ đó đi và thêm connection mới vào:

<add name=”DemoStudentConnection” providerName=”Data.SqlClient” connectionString=”Data Source=HaiDV-PC;Initial Catalog=DemoStudent;Integrated Security=False;User Id=sa;Password=xxxx;MultipleActiveResultSets=True”/>

(nhớ set lại username và password cho đúng)

  • Giờ mở giao diện Package Console Manager ra: Tool >NutGet Package Manager>Package Manager Console. Viết vào đó như sau: enable-migrations Enter cho chạy cậu lệnh, chạy xong các bạn sẽ thấy có một folder Migrations được thêm vào trong project, tiếp túc viết vào Console: add-migration Init-Db nó sẽ tạo ra một file cs như sau:

Các bạn chạy tiếp một lệnh: update-database sau đó mở SQL Server ra sẽ thấy một Database mới được thêm.

  • Như vậy đã xong việc tạo Model Code First và kết nối với SQL Server, tiếp theo chúng ta sẽ tạo Controller cho 2 class: ClassModel và StudentModel (tạo kiểu này cho nhanh)

  • Thế là tạm xong webapi trên server rồi, giờ chỉ việc mở postman lên và test thôi :D. Nói qua cho bạn nào chưa biết về postman là một ứng dụng khá là có ích dùng dể test apiResult…được tích hợp vào trình duyệt. Để tải các bạn lên https://www.getpostman.com/ rồi tải về về thôi
  • Các bạn mở giao diện postman lên và làm theo các bước sau đây nhớ là phải có Db mới test ra nhé, insert thử vài trường vào Db :

Lưu ý http://localhost:5392 là cổng của web mình bạn có thể xem công của web mình khi chạy web nó sẽ hiện lên thanh trình duyệt hoặc chuột phải vào project chọn Properties>Web

 

 

Series Angular2 – WebApi 1: Tổng quan và những phần mềm cần cài đặt

Ở loạt bài viết này mình sẽ hướng dẫn các bạn về cách sử dụng angular2 là ngôn ngữ client và asp.net web api là ngôn ngữ server.

Những phần mềm cần sử dụng trong series này mà các bạn cần chuẩn bị:

  • Visual Studio 2015 (tìm bản crack trên google, nên tải bản >= 2015 vì sẽ hỗ trợ tốt typescript)
  • NodeJS : download tại: https://nodejs.org
  • SQL Server >= 2012

Series này giúp các bạn bước đầu làm quen với việc xây dựng 1 website sử dụng asp.net Web api và Angular2: Rule hoạt động của web site như sau:

  • Web api sử dụng SQL Server, xử lý dữ liệu và trả về dưới dạng json, angular2 nhận giá trị và hiển thị trên màn hình, các xử lý post, put, delete được request từ angular2 đến các các controller trên web api, xử lý gọi đến các method thực hiện và hoạt động
  • Web api code first

Pipes trong Angular2 là cái quái gì?

Trong angular2 chúng ta sẽ thấy một từ khá là quen thuộc đó là Pipe thực ra nó là một Interface giúp chuyển đổi giá trị của dữ liệu mình mong muốn.

Có 2 cách để dùng Pipe:

  • Sử dụng selector để thay đổi giá trị hiển thị mong muốn(cái này chỉ để thay đổi hiển thị thôi còn giá trị gốc của nó vẫn vậy)
  • Gọi qua constructor để thay đổi giá trị mong muốn (như kiểu return về giá trị khác ấy)

Viết một Pipe:

Thành phần một pipe gồm:

pipes

1: import thư viện cần thiết

2: Khai báo Decorator Pipe (name: tên selector)

3: Class Pipe ở đây việc code(transform là một function kế thừa của PipeTransform dùng để return giá trị bạn mong muốn ở phần sử dụng pipe mình sẽ nói sau)

Cách sự dụng:

Cách 1: Ở đây mình dùng cái pipe ở trên để cắt lấy chuỗi “Hello HảiDV Blog 1234!” thành “Hello HảiDV Blog” để sử dụng cái Pipe trên chúng ta chỉ cần thêm selector của Pipe trên vào sau giá trị muốn thay đổi hiển thị: {{ name | subString }} nhớ là cần khai báo Pipe vào Decorator @NgModule nhé!

sudungpipe

Cách 2:  Như cách 1 là dùng khi hiển thị ngoài view html thì giá trị trước khi hiển thị sẽ được đưa vào Pipes và trả về giá trị khác hiển thị như mong muốn, ở cách là ta dùng như một cách convert giá trị dùng trong code. Như ví dụ một ta có một chuỗi “Hello HảiDV Blog 1234!” và muốn hiển thị là “Hello HảiDV Blog”

vidupipes2

ở đây các bạn thấy mình khai báo Pipes SubString sử dụng như một constructor. Mình hiển thị ra chuỗi cũng như ở ví dụ một chỉ khác là giá trị thực của chuỗi đó đã được thay đổi. Giá trị thực của là demo2 = “Hello HảiDV Blog”, còn ở ví dụ một giá trị thực của name =”Hello HảiDV Blog 1234!” chỉ khi hiển thị nó mới được modified đi thôi.
Tùy vào mục đích sử dụng chúng ta sẽ nên sử dụng cách nào cho hợp lý.

Pipes thường viết để dùng theo kiểu common thôi chứ bình thường chỉ cắt một số chữ như mình mà viết cả 1 cái pipes thì hơi phí.

Dưới đây là một số các Pipes có sẵn mà Angular2 đã cung cấp chúng ta chỉ việc khai báo và sử dụng thôi.

  • DatePipe:  Sử dụng: date_expression | date[:format] trong đó format có thể có các giá trị

'medium': equivalent to 'yMMMdjms' (e.g. Sep 3, 2010, 12:05:08 PM for en-US)

'short': equivalent to 'yMdjm' (e.g. 9/3/2010, 12:05 PM for en-US)

'fullDate': equivalent to 'yMMMMEEEEd' (e.g. Friday, September 3, 2010 for en-US)

'longDate': equivalent to 'yMMMMd' (e.g. September 3, 2010 for en-US)

'mediumDate': equivalent to 'yMMMd' (e.g. Sep 3, 2010 for en-US)

'shortDate': equivalent to 'yMd' (e.g. 9/3/2010 for en-US)

'mediumTime': equivalent to 'jms' (e.g. 12:05:08 PM for en-US)

'shortTime': equivalent to 'jm' (e.g. 12:05 PM for en-US)

cũng có thể viết kiểu “dd/MM/yyyy”

  • orderby, uppercase, lowercase… : đọc tên là biết để làm gì rồi.
  • CurrentcyPipe: ví dụ luôn “tiền | currency:’USD’:true:’1.2-2′” trong đó USA thì biết rồi nhá cái true ấy là sử dụng symbol khi hiển thị sẽ là $50 còn khi false là sử dụng code khi hiển thị sẽ là 50USD. Còn cái 1.2-2 thực ra là một cái Pipes khác DecimalPipe format của nó là {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits} dùng để hiển thị bao nhiêu số thập phân đằng sau dấu phẩy thôi các bạn test thử sẽ biết

Chúc thành công!

Ví dụ : https://plnkr.co/edit/AFwLmmoWeq7OOFR8EQiK?p=preview