摘要:使用搭建成熟可靠的后臺系統(tǒng)二構(gòu)建動態(tài)表單構(gòu)建一個動態(tài)表單,動態(tài)生成控件,驗證規(guī)則。現(xiàn)在來創(chuàng)建它的子組件從上面的組件可以看出,未來需要添加組件時,只需要添加一種類型,可以用決定顯示哪種類型的問題。
使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(二) 1.構(gòu)建動態(tài)表單
構(gòu)建一個動態(tài)表單,動態(tài)生成控件,驗證規(guī)則。
創(chuàng)建一個input組件,一個select組件
將組件注入到頁面中并顯示
前半部分直接借鑒官方文檔的寫法,后期開啟個性化定制后,功能強大!
在 theme/components 目錄下創(chuàng)建一個文件夾 dynamic-form
項目目錄結(jié)構(gòu)如下,下面跟著步驟一步一步來構(gòu)建
創(chuàng)建對象模型我們需要定義一個對象模型,用來描述表單功能需要的場景。相關(guān)功能非常之多(類似于 input select )。
先創(chuàng)建一個最基礎(chǔ)的基類,名為 QuestionBase,文件為 dynamic-form-base/question-base.ts
export class QuestionBase{ value: T; // 值,類型可選 key: string; // 字段名 label: string; // 控件前的文字提示 required: boolean; // 是否為必填 disabled: boolean; // 是否禁用 reg: string; // 正則 prompt: string; // 驗證不通過提示 order: number; // 排序 controlType: string; // 渲染類型 constructor(options: { value?: T, key?: string, label?: string, required?: boolean, disabled?: boolean, reg?: string, prompt?: string, order?: number, controlType?: string } = {}) { // 設(shè)置各個值的默認值 this.value = options.value; this.key = options.key || ""; this.label = options.label || ""; this.required = !!options.required; this.disabled = !!options.disabled; this.reg = options.reg || ""; this.prompt = options.prompt || ""; this.order = options.order || 0; this.controlType = options.controlType || ""; } }
在這個基礎(chǔ)上,我們派生出兩個類 InputQuestion 和 SelectQuestion ,代表文本框和下拉框。
這么做的原因是根據(jù)不同的控件,進行個性化定制,以及合理規(guī)范,還有動態(tài)渲染出合適的組件
InputQuestion 可以通過type屬性來支持多種HTML元素類型(例如: text number email) --- dynamic-form-base/question-input.ts
import { QuestionBase } from "./question-base"; export class InputQuestion extends QuestionBase{ controlType = "input"; type: string; constructor(options: {} = {}) { super(options); this.type = options["type"] || ""; } }
SelectQuestion 表示一個帶可選列表的選擇框
import { QuestionBase } from "./question-base"; export class SelectQuestion extends QuestionBase{ controlType = "select"; options: any[] = []; constructor(options: {} = {}) { super(options); this.options = options["options"] || []; } }
最后別忘了用 index.ts 將這三個模型導(dǎo)出
接下來,我們定義一個 QuestionControlService,一個可以把模型轉(zhuǎn)換為FormGroup的服務(wù)。 簡而言之,這個FormGroup使用問卷模型的元數(shù)據(jù),并允許我們設(shè)置默認值和驗證規(guī)則
question-control.service.ts
import { Injectable } from "@angular/core"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { QuestionBase } from "./dynamic-form-base"; @Injectable() export class QuestionControlService { constructor() { } // 轉(zhuǎn)化為控件 toFormGroup(questions: QuestionBase動態(tài)表單組件[]) { let group: any = {}; questions.forEach(question => { if (question.required) { // 選項為必填時 if (question.reg) { // 有正則的情況 group[question.key] = new FormControl(question.value || "", Validators.compose([Validators.required, Validators.pattern(question.reg)])); } else { group[question.key] = new FormControl(question.value || "", Validators.compose([Validators.required])); } } else if (!question.required && question.reg) { // 選項為非必填但是需要正則匹配的情況 group[question.key] = new FormControl(question.value || "", Validators.compose([Validators.pattern(question.reg)])); } else { group[question.key] = new FormControl(question.value || ""); } }); return new FormGroup(group); } }
現(xiàn)在我們已經(jīng)有了一個定義好的完整模型了,接著就可以開始構(gòu)建一個展現(xiàn)動態(tài)表單的組件。
DynamicFormComponent 是表單的主要容器和入口
dynamic-form.component.html
Saved the following values
{{payload}}
dynamic-form.component.ts
import { Component, Input, OnInit } from "@angular/core"; import { FormGroup } from "@angular/forms"; import { QuestionBase } from "./dynamic-form-base/question-base"; import { QuestionControlService } from "./question-control.service"; @Component({ selector: "dynamic-form", templateUrl: "./dynamic-form.component.html", providers: [QuestionControlService] }) export class DynamicFormComponent implements OnInit { @Input() questions: QuestionBase[] = []; form: FormGroup; payload = ""; constructor( private qcs: QuestionControlService ) { } ngOnInit() { console.log(this.questions); this.form = this.qcs.toFormGroup(this.questions); console.log(this.form); } onSubmit() { this.payload = JSON.stringify(this.form.value); } }
剛才創(chuàng)建的是一個組件入口,每個 question 都被綁定到了
現(xiàn)在來創(chuàng)建它的子組件 DynamicFormQuestionComponent
dynamic-form-question/dynamic-form-question.component.html
dynamic-form-question/dynamic-form-question.component.ts
import { Component, Input } from "@angular/core"; import { FormGroup } from "@angular/forms"; import { QuestionBase } from "../dynamic-form-base/question-base"; @Component({ selector: "df-question", templateUrl: "./dynamic-form-question.component.html" }) export class DynamicFormQuestionComponent { @Input() question: QuestionBase; @Input() form: FormGroup; get isValid() { return this.form.controls[this.question.key].valid } }
從上面的組件可以看出,未來需要添加組件時,只需要添加一種類型,可以用 ngSwitch 決定顯示哪種類型的問題。
在這兩個組件中,我們依賴Angular的formGroup來把模板HTML和底層控件對象連接起來,該對象從問卷問題模型里獲取渲染和驗證規(guī)則。
注意:每個目錄都需要用 index.ts 導(dǎo)出模塊, 這里需要在 theme/components 將我們注冊的組件統(tǒng)一導(dǎo)出。注冊組件
我們創(chuàng)建組件之后,需要將我們的組件注冊到 module 中,這里選擇 theme/nga.module.ts 注入我們的組件。
其實使用組件還需要注入 ReactiveFormsModule, ng2-admin 已經(jīng)幫我們注冊好了,所以我們這里只需要注冊我們創(chuàng)建的組件即可
方法如下圖,先引入
然后添加至 NGA_COMPONENTS
注冊ServiceDynamicForm 期望得到一個問題列表,該列表被綁定到@Input() questions屬性。
QuestionService 會返回為工作申請表定義的那組問題列表。在真實的應(yīng)用程序環(huán)境中,我們會從數(shù)據(jù)庫里獲得這些問題列表。
要維護控件,只要非常簡單的添加、更新和刪除 questions 數(shù)組中的對象就可以了。
切換到 pages 文件夾,開始使用我們上一章創(chuàng)建的 UserAddComponent
pages/user/user-list/user-add/user-add.service.ts
import { Injectable } from "@angular/core"; import { QuestionBase, InputQuestion, SelectQuestion } from "../../../../theme/components/dynamic-form/dynamic-form-base"; @Injectable() export class UserAddService { getQuestions() { let questions: QuestionBase[] = [ new SelectQuestion({ key: "brave", label: "Bravery Rating", value: "solid", options: [ { key: "Solid", value: "solid" }, { key: "Great", value: "great" }, { key: "Good", value: "good" }, { key: "Unproven", value: "unproven" } ], order: 3 }), new InputQuestion({ key: "firstName", label: "First name", value: "Bombasto", required: true, order: 1 }), new InputQuestion({ key: "emailAddress", label: "Email", type: "email", order: 2 }) ]; return questions.sort((a, b) => a.order - b.order); } }
需要在 html 文件以及 component 文件中顯示,所以修改一下這兩個文件
user-add.component.html
新增用戶組件
user-add.component.ts
import { Component } from "@angular/core"; import { UserAddService } from "./user-add.service"; import { QuestionBase } from "../../../../theme/components/dynamic-form/dynamic-form-base/question-base"; @Component({ selector: "ngt-user-add", templateUrl: "./user-add.component.html", providers: [UserAddService] }) export class UserAddComponent { public UserAddQuestions: QuestionBase[] = []; constructor( private service: UserAddService ) { this.UserAddQuestions = this.service.getQuestions(); } }
根據(jù) Angular 的模塊查找規(guī)則,所以這里還需要把 NgaModule 注入到 user.module.ts中,如下圖
然后打開瀏覽器,輸入 http://localhost:4200/#/pages/user/list/add
訪問效果如下圖,填入一些數(shù)據(jù),然后點擊保存,我們需要存入的數(shù)據(jù),顯示在了下方
動態(tài)表單的雛形已經(jīng)做出來了,現(xiàn)在還有幾個問題
樣式需要優(yōu)化
數(shù)據(jù)如何過濾優(yōu)化
數(shù)據(jù)如何提交
組件功能有些薄弱
這些問題我們會在后續(xù)的章節(jié)慢慢解決,可以期待。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88739.html
摘要:使用搭建成熟可靠的后臺系統(tǒng)三完善動態(tài)表單添加樣式。下一章會講解,一個集成的服務(wù),來完成我們的提交,在將來的篇章里會在我們的組件中加入使其變得更加靈活。 使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(三) 完善動態(tài)表單 添加樣式。 抽離組件。 添加組件樣式 上一篇文章創(chuàng)建了兩個,組件,現(xiàn)在使用bootstrap來給他們添加一些樣式 首先需要一個公用的 s...
摘要:使用搭建成熟可靠的后臺系統(tǒng)四完善動態(tài)表單組件添加正則驗證添加錯誤提示添加正則驗證先來設(shè)置一些錯誤提示,以及添加正則驗證上一章可能遺留了部分路徑錯誤,可以自行調(diào)整郵箱格式不正確請選擇這里是提供的一些正則 使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(四) 完善動態(tài)表單組件 添加正則驗證 添加錯誤提示 添加正則驗證 先來設(shè)置一些錯誤提示,以及添加正則驗證(...
摘要:注意在配置完成后,需要重新啟動項目使配置生效。每一行的內(nèi)容,由數(shù)據(jù)內(nèi)容決定,例如有三條數(shù)據(jù),應(yīng)顯示三行數(shù)據(jù),數(shù)據(jù)由組件自身請求獲取,所以應(yīng)該有一個自身的屬性用于承載數(shù)據(jù)。注意這里將換成了,所以組件的也需要替換,否則會報錯。 使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(六) 完善動態(tài)表單組件 先來張本章節(jié)最終效果圖showImg(https://segmen...
摘要:創(chuàng)建一個工具類,負責(zé)提供以及完成拼接參數(shù)的工作。根據(jù)我們的配置,來創(chuàng)建這個文件。因為是表單提交,所以我們新建一個服務(wù),由它來完成表單提交的最后一步。 使用ng2-admin搭建成熟可靠的后臺系統(tǒng) -- ng2-admin(五) 完善動態(tài)表單組件 升級Angular 4.1 -> 4.3 添加 json-server 模擬數(shù)據(jù) 創(chuàng)建自己的 http 完成一次表單提交 升級Angu...
摘要:云函數(shù)是萬金油為實現(xiàn)用戶游戲數(shù)據(jù)存儲和每日任務(wù)分發(fā),我們最先用了存儲服務(wù)和云引擎。不過我們并沒有用提供的來直接調(diào)用存儲服務(wù),而是選擇用調(diào)用云引擎里面的云函數(shù),然后通過云函數(shù)調(diào)用存儲服務(wù)來實現(xiàn)相應(yīng)的邏輯。 【 玩轉(zhuǎn) LeanCloud 】開發(fā)者投稿分享: 作者:趙天澤 作為一個通過 LeanCloud 入門后端開發(fā)的小白,一年多的開發(fā)歷程讓我收獲滿滿。多個項目也在 LeanCloud 可...
閱讀 1063·2021-11-24 09:39
閱讀 3602·2021-11-22 13:54
閱讀 2558·2021-10-11 10:59
閱讀 796·2021-09-02 15:40
閱讀 1036·2019-08-30 15:55
閱讀 1053·2019-08-30 13:57
閱讀 2314·2019-08-30 13:17
閱讀 3034·2019-08-29 18:32