iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0

現在我們透過設定檔產生表單
看起來很方便沒錯
不過如果有一些特殊情況
比如說市內電話 區碼 電話號碼 分機
三個欄位 如果用我們現在的設定方式
會變成三個欄位各有一塊區域
跟一般常見的輸入有點不一樣
既然這三個欄位常常一起出現
那是不是可以為了他們做一個特別的元件
其中再放他們自己的邏輯

現在開始思考設定檔要怎麼調整
首先分析一下我們現在的pageSetting

    title: string;
    form?: FormGroup;
    fieldSettings: FieldSetting[];

現在我們有個透過fieldSettings產生的form
這個form現在負責了檢核以及資料儲存的部分
現在我們要增加一個特殊元件要管理電話的部分
我們的目標有下列幾項

  • 區碼、電話號碼、分機 做一個專屬元件
  • 考慮到打API的時候處理資料的方便 資料要跟其他資料攤平在同一層
  • 由於這三個元件會有自身對自身的關聯 所以應該要給他們包一層formGroup 所以原本在fieldSetting產生Form的時候要有一段邏輯去判斷
    • input-form在決定顯示的field-tempate的時候 要判斷要不要顯示特殊模板
    • 在上述情況的時候 已經在特殊模板的欄位不能顯示

我們先增加電話相關的三個欄位

    {
        name: 'area1',
        cname: '電話區碼',
        inputType: 'text',
        placeholder: '',
        defaultValue: '00',
        validator: [Validators.maxLength(3)]
    },
    {
        name: 'phone1',
        cname: '電話號碼',
        inputType: 'text',
        placeholder: '0000000',
        defaultValue: '',
        validator: [Validators.maxLength(10)]
    },
    {
        name: 'ext1',
        cname: '電話分機',
        inputType: 'text',
        placeholder: '0000',
        required: true,
        defaultValue: '',
        validator: [Validators.maxLength(4)]
    },

現在我們要思考怎麼產生form
我們還是會有一個攤平的form裡面有所有的欄位
這些欄位應該會是所有fieldSettings的欄位
不過產生畫面的時候特殊元件還是會需要分組
所以會有一個innerForm去處理畫面上的資料

    {
        name: 'area1',
        cname: '電話欄位',
        inputType: 'text',
        groupName: 'phoneGroup1',
        groupType: 'phone-area',
        placeholder: '',
        defaultValue: '00',
        validator: [Validators.maxLength(3)]
    },
    {
        name: 'phone1',
        cname: '電話欄位',
        inputType: 'text',
        groupName: 'phoneGroup1',
        groupType: 'phone-number',
        placeholder: '0000000',
        defaultValue: '',
        validator: [Validators.maxLength(10)]
    },
    {
        name: 'ext1',
        cname: '電話欄位',
        inputType: 'text',
        groupName: 'phoneGroup1',
        groupType: 'phone-ext',
        placeholder: '0000',
        required: true,
        defaultValue: '',
        validator: [Validators.maxLength(4)]
    },

這邊的話再增加GroupName跟groupType的兩個設定
然後調整input-form的寫法

    innerForm = this.fb.group({});
    constructor(private fb: FormBuilder) { }

    ngOnChanges(): void
    {
        this.pageSetting.form = this.fb.group({});
        this.pageSetting.fieldSettings.forEach(setting =>
        {
            let newControl = this.fb.control(setting.defaultValue, { validators: setting.validator });
            if (!setting.groupName)
            {
                this.innerForm.addControl(setting.name, newControl);
            } else
            {
                if (!this.innerForm.contains(setting.groupName))
                {
                    this.innerForm.addControl(setting.groupName, new FormGroup({}));
                }
                (this.innerForm.get(setting.groupName) as FormGroup).addControl(setting.groupType!, this.fb.control(setting.defaultValue, { validators: setting.validator }))
            }
            (this.pageSetting.form as FormGroup).addControl(setting.name, newControl);
        })
    }

多使用一個innerForm去記錄當前頁面的狀態
然後遇到有groupName的欄位的時候
判斷是不是已經有這個formGroup
如果沒有就創造
如果有 就放在innerForm的這個formGroup下面
到這邊我們會獲得兩組Form

// innerForm 
{
    checkbox1: "1,2",
    number1: "123",password1: null,
    phoneGroup1: {phone-area: '00', phone-number: '', phone-ext: ''},
    radio1: "1",
    select1: "1",
    tel1: null,
    text1: "123"
}
// this.pageSetting.form
    area1:"00",
    checkbox1:"1,2",
    ext1: "",
    number1: "123",
    password1: null,
    phone1: "",
    radio1: "1",
    select1: "1",
    tel1: null,
    text1: "123"

上面的innerForm是用來再畫面呈現用的
改完以後發現畫面是這樣
https://ithelp.ithome.com.tw/upload/images/20240930/20168302Kcg6UbvH4g.png
電話欄位沒有消失
我們發現因為我們畫面是用fieldSetting去長的
理想一點要調整成顯示innerForm的內容
不過今天已經改太多東西了 就明天繼續吧

今日程式:day17


上一篇
第16天 版面調整
下一篇
第18天 組合元件-電話(中)
系列文
簡單的事 最困難-Angular動態Form元件30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言