摘要:創(chuàng)建一個(gè)工具類,負(fù)責(zé)提供以及完成拼接參數(shù)的工作。根據(jù)我們的配置,來創(chuàng)建這個(gè)文件。因?yàn)槭潜韱翁峤唬晕覀冃陆ㄒ粋€(gè)服務(wù),由它來完成表單提交的最后一步。
使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(五) 完善動態(tài)表單組件
升級Angular 4.1 -> 4.3(版本大于 4.3.0 可跳過)升級Angular 4.1 -> 4.3
添加 json-server 模擬數(shù)據(jù)
創(chuàng)建自己的 http
完成一次表單提交
因?yàn)?httpClient 支持的最低 Angular 版本為 4.3, 所以需要先升級我們的 Angular
如下圖 配置 package.json
然后需要修改一個(gè)配置項(xiàng),兼容到 4.3.0 版本
tsconfig.json 添加一行
"paths": { "@angular/*": ["../node_modules/@angular/*"] }
這樣便完成了版本的升級
添加 json-server 模擬數(shù)據(jù)我們完成一個(gè)數(shù)據(jù)查詢,提交需要一些模擬數(shù)據(jù),json-server 工具可以幫助我們,全局安裝
npm i json-server -g
在 package.json 中的 scripts 添加一行
"db:mock": "json-server --watch ./db/db.json"
我們現(xiàn)在需要創(chuàng)建一個(gè) json 文件,用于裝載我們的模擬數(shù)據(jù),根據(jù)上述命令,在項(xiàng)目根目錄創(chuàng)建
db/db.json
{ "user": [ { "id": 1, "firstName": "張小", "emailAddress": "15135131@qq.com", "brave": "solid" } ] }
打開一個(gè)命令行窗口,在項(xiàng)目文件夾執(zhí)行
npm run db:mock
我們的 json-server 就啟動了,現(xiàn)在來回到我們的項(xiàng)目
在提交表單之前,我們需要 ajax 去提交我們的數(shù)據(jù),這時(shí)候涉及到服務(wù),數(shù)據(jù)驗(yàn)證,處理 response,這時(shí)候需要創(chuàng)建一套 http/httpClient 去負(fù)責(zé)這些任務(wù)。
創(chuàng)建一個(gè) http 工具類,負(fù)責(zé)提供 header, host, 以及完成拼接 url, 參數(shù)的工作。 根據(jù)我們的 json-server 配置,來創(chuàng)建這個(gè)文件。
api/http/http.service.ts
import { Injectable } from "@angular/core"; import { HttpHeaders } from "@angular/common/http"; @Injectable() export class HttpComponentUtil { public headers = new HttpHeaders({ "Content-Type": "application/json" }); private url: string = "http://localhost:3000/"; public getUrl(url: string): string { return this.url + url; } }
創(chuàng)建 http 的統(tǒng)一攔截服務(wù),做統(tǒng)一攔截,并且在未來做一些通用的工作
api/http/noopInterceptor.ts
import { Injectable } from "@angular/core"; import { Observable } from "rxjs/Observable"; import "rxjs/Rx"; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse } from "@angular/common/http"; @Injectable() export class NoopInterceptor implements HttpInterceptor { intercept( req: HttpRequest, next: HttpHandler ): Observable > { const started = Date.now(); return next .handle(req) .do(event => { if (event instanceof HttpResponse) { const elapsed = Date.now() - started; console.log(`Request for ${req.urlWithParams} took ${elapsed} ms.`); } }); } }
http 的統(tǒng)一攔截,還需要在 appModule.ts 中多帶帶注冊
app.module.ts
@NgModule({ ... providers: [ ... { provide: HTTP_INTERCEPTORS, useClass: NoopInterceptor, multi: true, } ] });
當(dāng) http 請求出錯(cuò)時(shí),需要做一些錯(cuò)誤處理,現(xiàn)在來創(chuàng)建一個(gè)服務(wù),做統(tǒng)一的錯(cuò)誤處理
api/http/handle.service.ts
import { Injectable, Inject } from "@angular/core"; import { Location } from "@angular/common"; import { Router, ActivatedRoute, Params } from "@angular/router"; import { Observable } from "rxjs/Observable"; import swal from "sweetalert2"; @Injectable() export class HandleService { constructor( private router: Router, private _location: Location ) { }; // 處理系統(tǒng)錯(cuò)誤 handleError(err: any): Observable{ let errMsg = "發(fā)生未知錯(cuò)誤,請重試"; if (typeof err == "object" && err.status !== undefined) { if (err.status == 404) { errMsg = "服務(wù)器處理異常,請重試"; } else if (err.status == 401) { swal("當(dāng)前頁面無權(quán)限查看", "", "warning"); this._location.back(); return Observable.empty(); } else if (err.status == 504) { errMsg = "服務(wù)器請求超時(shí),請重試"; } else if (err.status == 503) { errMsg = "相關(guān)服務(wù)正在部署發(fā)布,請稍等"; } else { errMsg = err.json().message; } } swal(errMsg, "", "error"); return Observable.empty(); } // 處理returnCode 這里假定接口 200 通過后,后端返回的狀態(tài)碼為 returnCode handleStatus(result: any): Observable { switch ((result.returnCode && String(result.returnCode)) || "201") { case "201": return Observable.of(result); case "1000": return Observable.of(result); case "1001": swal("當(dāng)前頁面無權(quán)限查看", "", "warning"); this._location.back(); return Observable.empty(); case "1002": // 數(shù)據(jù)為空 return Observable.of(result); default: swal("無法識別的錯(cuò)誤碼,請聯(lián)系管理員", "", "error"); return Observable.empty(); } } }
上面有兩個(gè)依賴注入,需要在 providers 注入,現(xiàn)在創(chuàng)建一個(gè)文件來提供注入
api/index.ts
import { HttpComponentUtil } from "./http/http.service"; import { HandleService } from "./http/handle.service"; export const API_SERVICE = [ HttpComponentUtil, HandleService ];
pages/pages.module.ts 中注入這兩個(gè)服務(wù)
@NgModule({ imports: [CommonModule, AppTranslationModule, NgaModule, routing], declarations: [Pages], providers: [ ...API_SERVICE ] })
到這里,http 服務(wù)創(chuàng)建完成,下半部分在表單提交時(shí)完成,屬于應(yīng)用層
完成一次表單提交完成表單提交,需要用到 ajax, 我們將使用 httpClient 完成 ajax 的工作,我們需要先注入 HttpClientModule, 在 nga.module.ts 中注入,這里不貼代碼了
注入完成后,現(xiàn)在來開始編寫我們的各項(xiàng)請求實(shí)例。
因?yàn)槭潜韱翁峤唬晕覀冃陆ㄒ粋€(gè)服務(wù),由它來完成表單提交的最后一步。
theme/components/dynamic-form/dynamic-form.service.ts
import { Observable } from "rxjs/Rx"; import { Injectable } from "@angular/core"; import { HttpClient, HttpEvent, HttpHeaders } from "@angular/common/http"; import { HttpComponentUtil } from "../../../pages/api/http/http.service"; import { HandleService } from "../../../pages/api/http/handle.service"; @Injectable() export class DynamicFormService { constructor( private http: HttpClient, private https: HttpComponentUtil, private handleService: HandleService ) {} public getList(url: string, params: {} = {}): Observable{ return new Observable(); } /** * * * @param {string} url * @param {{}} [params={}] 請求入?yún)⒌?body,參數(shù) * @returns {Observable } 返回一個(gè)可供訂閱的觀察者對象 * @memberof DynamicFormService */ public saveQuery(url: string, params: {} = {}): Observable { let api_url: string = this.https.getUrl(url); // 利用公用的 http 服務(wù),拼接獲取url return this.http.post(api_url, params, { headers: this.https.headers }) .map((res: any) => ( this.handleService.handleStatus(res)).value || undefined) // 捕獲錯(cuò)誤碼 .catch(err => this.handleService.handleError(err)); // 捕獲系統(tǒng)錯(cuò)誤 } }
上面構(gòu)建了包含一個(gè) saveQuery 功能的服務(wù), 代碼已經(jīng)添加注釋,可以仔細(xì)研讀一下。
saveQuery 的兩個(gè)參數(shù),params 應(yīng)該由動態(tài)表單直接獲取提供,url 應(yīng)該由頁面提供, 所以 DynamicFormComponent 應(yīng)該接入一個(gè) Input 參數(shù)
@Input() config: FormConfig;
dynamic-form/form-base.ts
export interface FormConfig { url: string; }
現(xiàn)在需要在頁面中,把 config 參數(shù)傳入組件
user-add.component.ts
... export class UserAddComponent { public UserAddConfig: FormConfig = { url: "user" } ... }
user-add.component.html
新增用戶組件
現(xiàn)在回到組件,我們將完成我們的提交表單操作,現(xiàn)在思考兩個(gè)問題,提交成功后的操作
成功提示
返回到上一個(gè)頁面
所以我們的組件應(yīng)該是
dynamic-form.component.ts
import { Component, Input, OnInit } from "@angular/core"; import { Location } from "@angular/common"; import { FormGroup } from "@angular/forms"; import { QuestionBase } from "../dynamic-form-components/dynamic-form-base/question-base"; import { QuestionControlService } from "./question-control.service"; import { DynamicFormService } from "./dynamic-form.service"; import "style-loader!./dynamic-fom-components.component.scss"; import { FormConfig } from "./form-base"; import swal from "sweetalert2"; @Component({ selector: "dynamic-form", templateUrl: "./dynamic-form.component.html", styleUrls: ["./dynamic-form.component.scss"], providers: [QuestionControlService, DynamicFormService] }) export class DynamicFormComponent implements OnInit { @Input() questions: QuestionBase[] = []; @Input() config: FormConfig; form: FormGroup; payload = ""; constructor( private qcs: QuestionControlService, private service: DynamicFormService, private _location: Location ) {} ngOnInit() { this.form = this.qcs.toFormGroup(this.questions); } onSubmit() { this.payload = JSON.stringify(this.form.value); this.service.saveQuery(this.config.url, this.payload) .subscribe((res: Response) => { console.log(res); swal("success","","success").then(() => { this._location.back(); }); }) } }
這里使用到了 sweetalert2 組件,需要讀者自行安裝,并且在
pages.component.ts 中引入樣式
import "style-loader!sweetalert2/dist/sweetalert2.min.css";
現(xiàn)在打開瀏覽器,來測試一下我們剛才的頁面,測試結(jié)果如下
添加成功和失敗,都有對應(yīng)提示,并且提交成功后會返回到上一頁,現(xiàn)在來看看 db.json,如下圖,數(shù)據(jù)也被添加進(jìn)了json!
我們的數(shù)據(jù)已經(jīng)存入,下章就來講解,如何搭建一個(gè)動態(tài)表格組件,來展示我們的數(shù)據(jù),后續(xù)會把增刪改查功能一一介紹,在介紹完基礎(chǔ)組件后,會注入 redux 方便我們的狀態(tài)管理
(此章代碼在ng2-admin 的 httpclient-submit 分支上,可以pull 下來,方便讀者練習(xí))
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90639.html
摘要:使用搭建成熟可靠的后臺系統(tǒng)三完善動態(tài)表單添加樣式。下一章會講解,一個(gè)集成的服務(wù),來完成我們的提交,在將來的篇章里會在我們的組件中加入使其變得更加靈活。 使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(三) 完善動態(tài)表單 添加樣式。 抽離組件。 添加組件樣式 上一篇文章創(chuàng)建了兩個(gè),組件,現(xiàn)在使用bootstrap來給他們添加一些樣式 首先需要一個(gè)公用的 s...
摘要:使用搭建成熟可靠的后臺系統(tǒng)四完善動態(tài)表單組件添加正則驗(yàn)證添加錯(cuò)誤提示添加正則驗(yàn)證先來設(shè)置一些錯(cuò)誤提示,以及添加正則驗(yàn)證上一章可能遺留了部分路徑錯(cuò)誤,可以自行調(diào)整郵箱格式不正確請選擇這里是提供的一些正則 使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(四) 完善動態(tài)表單組件 添加正則驗(yàn)證 添加錯(cuò)誤提示 添加正則驗(yàn)證 先來設(shè)置一些錯(cuò)誤提示,以及添加正則驗(yàn)證(...
摘要:使用搭建成熟可靠的后臺系統(tǒng)二構(gòu)建動態(tài)表單構(gòu)建一個(gè)動態(tài)表單,動態(tài)生成控件,驗(yàn)證規(guī)則。現(xiàn)在來創(chuàng)建它的子組件從上面的組件可以看出,未來需要添加組件時(shí),只需要添加一種類型,可以用決定顯示哪種類型的問題。 使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(二) 1.構(gòu)建動態(tài)表單 構(gòu)建一個(gè)動態(tài)表單,動態(tài)生成控件,驗(yàn)證規(guī)則。 創(chuàng)建一個(gè)input組件,一個(gè)select組件 將...
摘要:注意在配置完成后,需要重新啟動項(xiàng)目使配置生效。每一行的內(nèi)容,由數(shù)據(jù)內(nèi)容決定,例如有三條數(shù)據(jù),應(yīng)顯示三行數(shù)據(jù),數(shù)據(jù)由組件自身請求獲取,所以應(yīng)該有一個(gè)自身的屬性用于承載數(shù)據(jù)。注意這里將換成了,所以組件的也需要替換,否則會報(bào)錯(cuò)。 使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(六) 完善動態(tài)表單組件 先來張本章節(jié)最終效果圖showImg(https://segmen...
摘要:云函數(shù)是萬金油為實(shí)現(xiàn)用戶游戲數(shù)據(jù)存儲和每日任務(wù)分發(fā),我們最先用了存儲服務(wù)和云引擎。不過我們并沒有用提供的來直接調(diào)用存儲服務(wù),而是選擇用調(diào)用云引擎里面的云函數(shù),然后通過云函數(shù)調(diào)用存儲服務(wù)來實(shí)現(xiàn)相應(yīng)的邏輯。 【 玩轉(zhuǎn) LeanCloud 】開發(fā)者投稿分享: 作者:趙天澤 作為一個(gè)通過 LeanCloud 入門后端開發(fā)的小白,一年多的開發(fā)歷程讓我收獲滿滿。多個(gè)項(xiàng)目也在 LeanCloud 可...
閱讀 1364·2021-11-22 15:25
閱讀 3358·2021-10-21 09:38
閱讀 1575·2021-10-19 13:21
閱讀 1000·2021-09-06 15:00
閱讀 1679·2019-08-30 15:44
閱讀 2595·2019-08-29 15:40
閱讀 3447·2019-08-29 13:44
閱讀 2055·2019-08-26 16:56