實戰Angular2+web api增刪改查(三)
Angular2 開發
本示例使用了Angular2 RC4版本,另外由於使用了bootstrap,所以需要html中引入對應的css及js檔案
入口
import { bootstrap } from '@angular/platform-browser-dynamic'; import {myApp} from "./myApp"; import {HTTP_PROVIDERS} from "@angular/http"; bootstrap(myApp,[HTTP_PROVIDERS]).catch(err=>console.error(err));
這裡由於要使用angular中的http所以需要在入口處先注入
服務
在此之前我們需要先定義DTO,由於我們傳輸DTO使用的是Json格式所以angular的DTO與webapi中DTO型別名稱一致即可。
export interface groupDto { ID:string; GROUPNAME:string; NORDER:number; PARENTID:string; GROUPTYPE:string; GROUPCODE:string; }
下面將定義groupservice來從webapi中獲取資料、更新資料
/** * Created by Administrator on 2016-06-30. */import {Injectable} from "@angular/core"; import {Http, Headers} from "@angular/http"; import 'rxjs/Rx'; import {groupDto} from "./models/groupDto"; import {Observer, Observable} from "rxjs/Rx"; @Injectable() export class groupservice{ isSubmit:Observable<boolean>; private observer:Observer<boolean>; private _baseURL: string="http://localhost:23273/api/GroupList"; constructor(private _http: Http) { this.isSubmit= new Observable<boolean>(observer=>this.observer=observer).share(); } getGroupList() { return this._http.get(this._baseURL).map(responce => responce.json()); } getGroup(id:string){ return this._http.get(this._baseURL+"/"+id).map(responce => responce.json()); } addGroup(item:groupDto){ var json = JSON.stringify(item); var params = 'json=' + json; var headers = new Headers(); headers.append('Content-Type','application/json'); headers.append('Accept','application/json'); return this._http.post(this._baseURL,JSON.stringify(item),{headers: headers}).subscribe( data=>{console.log(data);}, err => {console.log(err);}, () => { console.log("Complete"); if(this.observer!==undefined) this.observer.next(true); } ); } editGroup(id:string,item:groupDto){ var json = JSON.stringify(item); var params = 'json=' + json; var headers = new Headers(); headers.append('Content-Type','application/json'); headers.append('Accept','application/json'); return this._http.put(this._baseURL+"/"+id,JSON.stringify(item),{headers: headers}).subscribe( data=>{console.log(data);}, err => {console.log(err);}, () => { console.log("Complete"); if(this.observer!==undefined) this.observer.next(true); } ); } delGroup(id:string){ var headers = new Headers(); headers.append('Content-Type','application/json'); headers.append('Accept','application/json'); return this._http.delete(this._baseURL+"/"+id).subscribe( data=>{console.log(data)}, err=>{console.log(err)}, ()=> { console.log("Complete"); if (this.observer !== undefined) this.observer.next(true); } ); } }
這裡可以看到這個服務申明瞭@Injectable()也就是說是可被注入的,在這個服務的構造中我們注入http服務,為了保證我們資料更新能夠被其他元件檢測到故在此還是用了觀察模式(isSubmit),在資料更新後需要釋出這個(isSubmit)變化,即可保證凡是訂閱了該變化的元件都可及時進行資料處理。
這裡重點需要注意在呼叫http傳遞引數時需要加入http的頭部資訊,指定引數格式為Json。
父元件定義
/** * Created by Administrator on 2016-06-30. */ import {Component,ViewChild} from "@angular/core"; import {groupservice} from "./group.Service"; import {groupDto} from "./models/groupDto"; import {addgroup} from "./addgroup.component"; import {ConfirmOptions} from "../components/confirm/confirmOptions.provider"; import {Confirm} from "../components/confirm/confirm.directive"; import {ConfirmPopover} from "../components/confirm/confirmPopover.component"; import {Position} from "../components/confirm/position.provider" import {PositionService} from "../components/confirm/position/position"; import {editgroup} from "./editgroup.component"; @Component( { selector:"group", templateUrl:"./app/curd/groupmanager.html", providers:[groupservice, ConfirmOptions, {provide: Position, useClass: PositionService} ], directives:[ addgroup, Confirm, editgroup ], precompile: [ ConfirmPopover ], } ) export class group { @ViewChild('addGroupModal') addgroupmodal:addgroup; @ViewChild('editGroupModal') editgroupmodal:editgroup; groupdto:groupDto[]; subscription:any; private data:Array<any> ; constructor(private groupservice:groupservice) { //this.length = this.data.length; } onAdd() { this.addgroupmodal.open(); } onEdit(id:string){ this.editgroupmodal.open(id); } ngOnInit() { this.groupservice.getGroupList().subscribe(p=> { this.groupdto = p; }); this.subscription = this.groupservice.isSubmit.subscribe(status=> { if (status) { this.groupservice.getGroupList().subscribe(p=> { this.groupdto = p }); } }); //this.onChangeTable(this.config); } ngOnDestroy() { this.subscription.unsubscribe(); } onDel(id:string) { this.groupservice.delGroup(id); } }
此處有一點複雜,在該元件中我使用了Modal視窗(單獨的一個元件),即在新增、修改時彈出視窗進行資料編輯,同時在刪除時我增加的提示資訊,確認後才能實際進行刪除操作。
Template
模板使用了單獨的html檔案
<div> <div class="btn-group"> <button type="button" class="btn btn-default" (click)="onAdd()">新增部門</button> </div> <div> <table class=" table table-striped table-bordered dataTable"> <thead> <tr> <th>序號</th> <th > 單位編號 </th> <th> 單位名稱 </th> <th> 排序號 </th> <th> 操作 </th> </tr> </thead> <tbody> <tr *ngFor="let item of groupdto ; let i = index"> <td>{{i+1}}</td> <td>{{item.GROUPCODE}}</td> <td>{{item.GROUPNAME}}</td> <td>{{item.NORDER}}</td> <td> <button type="button" class="btn-danger" mwl-confirm title="提示" message="您確定要刪除嗎" confirmText="確定" cancelText="取消" placement="left" (confirm)="onDel(item.ID)" (cancel)="cancelClicked = true" confirmButtonType="danger" cancelButtonType="default" ><i class="icon-remove"></i></button> <button type="button" class="btn-info" (click)="onEdit(item.ID)"><i class="icon-edit-sign"></i></button> </td> </tr> </tbody> </table> </div> </div> <div> <add-group #addGroupModal></add-group> </div> <div> <edit-group #editGroupModal></edit-group> </div>
provider
在providers中我引入了前面建立的服務,由於這是父元件在此處引入後,子元件在注入時就無需再引入groupservice,當然也可以在入口的bootstrap中注入,這樣就無需再providers中引入了,具體差異見前面的學習資料。下面的ConfirmOptions和PositionService等都是用於提示框使用的服務。
Directives
在模板中使用了兩個子元件(add-group,edit-group)所以需要在Directives中宣告。
資料獲取
本例中在元件載入時會呼叫groupsevice獲取資料並載入,所以需要在ngOnInit中呼叫服務獲取資料,同時訂閱groupsevice中的isSubmit,在其更新後再次呼叫服務獲取資料以保障資料同步顯示。
資料更新
這裡使用了@ViewChild('addGroupModal') addgroupmodal:addgroup;
其中@ViewChild('addGroupModal') 與我們在模板中定義的子元件標籤<add-group#addGroupModal></add-group>保持一致。
通過ViewChild的定義,下面我們就能使用子元件的方法彈出視窗。
onEdit(id:string){
this.editgroupmodal.open(id);
}
子元件
/** * Created by Administrator on 2016-07-11. */ import {Component,ViewChild} from "@angular/core"; import {groupservice} from "./group.Service"; import {FormBuilder, Control, Validators, ControlGroup} from "@angular/common"; import {groupDto} from "./models/groupDto"; import {MODAL_DIRECTIVES} from "../components/modal/ng2-bs3-modal"; import {ModalComponent} from "../components/modal/components/modal"; @Component({ selector:"edit-group", templateUrl:"./app/curd/editgroup.html", directives: [MODAL_DIRECTIVES,ModalComponent ] }) export class editgroup{ groupdto:groupDto; groupCode:Control; groupName:Control; norder:Control; form: ControlGroup; subscription: any; constructor(private groupservice:groupservice,private builder: FormBuilder) { var obj={ID:"1",GROUPCODE:"",GROUPNAME:"",NORDER:1,PARENTID:"",GROUPTYPE:""}; this.groupdto=obj; this.groupCode = new Control('', Validators.compose([Validators.required, Validators.maxLength(10)])); this.groupName = new Control('', Validators.compose([Validators.required, Validators.maxLength(20)])); this.norder=new Control('',Validators.required); this.form= builder.group({ groupCode: this.groupCode, groupName: this.groupName, norder: this.norder }); } @ViewChild('myModal') modal: ModalComponent; close() { this.modal.close(); } open(id:string) { this.groupservice.getGroup(id).subscribe(p=>{ this.groupdto=p; }) this.modal.open(); } onSubmit(event){ this.groupservice.editGroup(this.groupdto.ID,this.groupdto); this.modal.close(); } ngOnInit(){ this.subscription=this.groupservice.isSubmit.subscribe(); } ngOnDestroy(){ this.subscription.unsubscribe(); } }
模板
<modal #myModal> <modal-header> <h4 class="modal-title">編輯單位</h4> </modal-header> <modal-body> <form [ngFormModel]="form" (submit)="onSubmit(planetform.value)" #planetform="ngForm"> <div class="form-group" > <label for="inputGroupCode">單位編號</label> <input type="text" class="form-control" id="inputGroupCode" placeholder="單位編號" ngControl="groupCode" [(ngModel)]="groupdto.GROUPCODE" > <div [hidden]="groupCode.valid || groupCode.pristine" class="alert alert-danger"> 單位編碼不能為空或長度不能超過10個字元 </div> </div> <div class="form-group"> <label for="inputGroupName">單位名稱</label> <input type="text" class="form-control" id="inputGroupName" placeholder="單位名稱" ngControl="groupName" [(ngModel)]="groupdto.GROUPNAME" > <div [hidden]="groupName.valid || groupName.pristine" class="alert alert-danger"> 單位名稱不能為空或長度不能超過20個字元 </div> </div> <div class="form-group"> <label for="exampleInputFile">排序碼</label> <input type="number" id="exampleInputFile" ngControl="norder" [(ngModel)]="groupdto.NORDER"> </div> <button type="submit" class="btn btn-primary" [disabled]="!form.valid">提交</button> </form> </modal-body> <modal-footer> <button type="button" class="btn btn-primary" (click)="modal.close()">關閉</button> </modal-footer> </modal>
這裡可以看到使用的是bootstrap中的modal,所以注意要在首頁html中要引入bootstrap及jquery。
在這個子元件中使用From中使用了資料驗證,如果驗證不通過([disabled]="!form.valid")則提交按鈕不能使用。
<button type="submit" class="btn btn-primary" [disabled]="!form.valid">提交</button>
Form使用
此例中使用的angular2的formbuilder方式建立表單,所以需要在建構函式中注入
this.groupCode = new Control('', Validators.compose([Validators.required,Validators.maxLength(10)]));
這裡定義的groupCode使用了組合驗證,與下面input中的ngControl名稱一致,ngModel繫結的是例項化的Dto
<input type="text" class="form-control" id="inputGroupCode" placeholder="單位編號" ngControl="groupCode" [(ngModel)]="groupdto.GROUPCODE" >
最後上圖片