摘要:使用搭建成熟可靠的后臺系統二構建動態表單構建一個動態表單,動態生成控件,驗證規則。現在來創建它的子組件從上面的組件可以看出,未來需要添加組件時,只需要添加一種類型,可以用決定顯示哪種類型的問題。
使用ng2-admin搭建成熟可靠的后臺系統 -- ng2-admin(二) 1.構建動態表單
構建一個動態表單,動態生成控件,驗證規則。
創建一個input組件,一個select組件
將組件注入到頁面中并顯示
前半部分直接借鑒官方文檔的寫法,后期開啟個性化定制后,功能強大!
在 theme/components 目錄下創建一個文件夾 dynamic-form
項目目錄結構如下,下面跟著步驟一步一步來構建
創建對象模型我們需要定義一個對象模型,用來描述表單功能需要的場景。相關功能非常之多(類似于 input select )。
先創建一個最基礎的基類,名為 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 } = {}) { // 設置各個值的默認值 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 || ""; } }
在這個基礎上,我們派生出兩個類 InputQuestion 和 SelectQuestion ,代表文本框和下拉框。
這么做的原因是根據不同的控件,進行個性化定制,以及合理規范,還有動態渲染出合適的組件
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 將這三個模型導出
接下來,我們定義一個 QuestionControlService,一個可以把模型轉換為FormGroup的服務。 簡而言之,這個FormGroup使用問卷模型的元數據,并允許我們設置默認值和驗證規則
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() { } // 轉化為控件 toFormGroup(questions: QuestionBase動態表單組件[]) { 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); } }
現在我們已經有了一個定義好的完整模型了,接著就可以開始構建一個展現動態表單的組件。
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); } }
剛才創建的是一個組件入口,每個 question 都被綁定到了
現在來創建它的子組件 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和底層控件對象連接起來,該對象從問卷問題模型里獲取渲染和驗證規則。
注意:每個目錄都需要用 index.ts 導出模塊, 這里需要在 theme/components 將我們注冊的組件統一導出。注冊組件
我們創建組件之后,需要將我們的組件注冊到 module 中,這里選擇 theme/nga.module.ts 注入我們的組件。
其實使用組件還需要注入 ReactiveFormsModule, ng2-admin 已經幫我們注冊好了,所以我們這里只需要注冊我們創建的組件即可
方法如下圖,先引入
然后添加至 NGA_COMPONENTS
注冊ServiceDynamicForm 期望得到一個問題列表,該列表被綁定到@Input() questions屬性。
QuestionService 會返回為工作申請表定義的那組問題列表。在真實的應用程序環境中,我們會從數據庫里獲得這些問題列表。
要維護控件,只要非常簡單的添加、更新和刪除 questions 數組中的對象就可以了。
切換到 pages 文件夾,開始使用我們上一章創建的 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(); } }
根據 Angular 的模塊查找規則,所以這里還需要把 NgaModule 注入到 user.module.ts中,如下圖
然后打開瀏覽器,輸入 http://localhost:4200/#/pages/user/list/add
訪問效果如下圖,填入一些數據,然后點擊保存,我們需要存入的數據,顯示在了下方
動態表單的雛形已經做出來了,現在還有幾個問題
樣式需要優化
數據如何過濾優化
數據如何提交
組件功能有些薄弱
這些問題我們會在后續的章節慢慢解決,可以期待。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88739.html
摘要:使用搭建成熟可靠的后臺系統三完善動態表單添加樣式。下一章會講解,一個集成的服務,來完成我們的提交,在將來的篇章里會在我們的組件中加入使其變得更加靈活。 使用ng2-admin搭建成熟可靠的后臺系統 -- ng2-admin(三) 完善動態表單 添加樣式。 抽離組件。 添加組件樣式 上一篇文章創建了兩個,組件,現在使用bootstrap來給他們添加一些樣式 首先需要一個公用的 s...
摘要:使用搭建成熟可靠的后臺系統四完善動態表單組件添加正則驗證添加錯誤提示添加正則驗證先來設置一些錯誤提示,以及添加正則驗證上一章可能遺留了部分路徑錯誤,可以自行調整郵箱格式不正確請選擇這里是提供的一些正則 使用ng2-admin搭建成熟可靠的后臺系統 -- ng2-admin(四) 完善動態表單組件 添加正則驗證 添加錯誤提示 添加正則驗證 先來設置一些錯誤提示,以及添加正則驗證(...
摘要:注意在配置完成后,需要重新啟動項目使配置生效。每一行的內容,由數據內容決定,例如有三條數據,應顯示三行數據,數據由組件自身請求獲取,所以應該有一個自身的屬性用于承載數據。注意這里將換成了,所以組件的也需要替換,否則會報錯。 使用ng2-admin搭建成熟可靠的后臺系統 -- ng2-admin(六) 完善動態表單組件 先來張本章節最終效果圖showImg(https://segmen...
摘要:創建一個工具類,負責提供以及完成拼接參數的工作。根據我們的配置,來創建這個文件。因為是表單提交,所以我們新建一個服務,由它來完成表單提交的最后一步。 使用ng2-admin搭建成熟可靠的后臺系統 -- ng2-admin(五) 完善動態表單組件 升級Angular 4.1 -> 4.3 添加 json-server 模擬數據 創建自己的 http 完成一次表單提交 升級Angu...
摘要:云函數是萬金油為實現用戶游戲數據存儲和每日任務分發,我們最先用了存儲服務和云引擎。不過我們并沒有用提供的來直接調用存儲服務,而是選擇用調用云引擎里面的云函數,然后通過云函數調用存儲服務來實現相應的邏輯。 【 玩轉 LeanCloud 】開發者投稿分享: 作者:趙天澤 作為一個通過 LeanCloud 入門后端開發的小白,一年多的開發歷程讓我收獲滿滿。多個項目也在 LeanCloud 可...
閱讀 1049·2021-11-24 09:39
閱讀 3580·2021-11-22 13:54
閱讀 2542·2021-10-11 10:59
閱讀 773·2021-09-02 15:40
閱讀 1025·2019-08-30 15:55
閱讀 1042·2019-08-30 13:57
閱讀 2305·2019-08-30 13:17
閱讀 3025·2019-08-29 18:32