iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0

昨天我們嘗試寫電話的組合元件
卻發現我們的程式又需要重構了
昨天新增了innerForm的部分
現在要來調整input-form的顯示條件
原本是採用fieldSettings裡面的陣列
現在要改成使用我們整理後的innerForm的部分
首先增加一個function可以接收formGroup然後取得裡面的value值

    // input-form.component.ts
    // 取得該區域欄位列表
    getGroupList(group: FormGroup)
    {
        let Result = Object.keys(group.value).map(obj =>
        {
            let innerControl = group.get(obj)
            if (innerControl?.value !== null && typeof innerControl?.value === 'object')
            {
                return innerControl
            } else 
            {
                return obj;
            }
        });
        return Result;
    }

以上產生的陣列會替換掉原本fieldSettings產生的form-input.component.html

//form-input.component.html
<div>
  {{ pageSetting.title }}
  <div [formGroup]="pageSetting.form!" *ngIf="pageSetting.form" class="row">
    <div *ngFor="let fieldObj of getGroupList(innerForm)" class="col-6">
      <ng-container *ngIf="typeof(fieldObj) === 'string'">
        <app-field-template
          [fieldSetting]="getSettingByName(pageSetting.fieldSettings, fieldObj)"
          [control]="getControl(fieldObj)"
        >
        </app-field-template>
      </ng-container>

      <ng-container *ngIf="typeof(fieldObj) !== 'string'">
        <app-combo-phone
          [fieldSettings]="
            getSettingsByForm(pageSetting.fieldSettings, fieldObj)
          "
          [inputForm]="fieldObj"
        >
        </app-combo-phone>
      </ng-container>
      <!-- {{ getControl(fieldSetting.name).value }} -->
    </div>
  </div>
</div>

這樣innerForm下面有兩種資料格式
一種是普通的元件 裡面是FromControl
透過getGroupList取出來的陣列
對應的fieldObj是string
另一種是組合的特殊元件 我們在產生innerForm的時候就處理成formGroup了
對應的filedObj是object
於是畫面上我們有多加一個邏輯
如果fieldObj的type是string 則走回原本的普通元件規則
如果不是 就是我們這次新增的面板
裡面目前是我們新寫的電話組合元件

但我們電話組合元件要吃什麼呢
理想一點 我們要給他裡面的三個欄位的formControl
這個我們已經包成一個formGroup了 也就是fieldObj的這個物件
另外我們想要丟這三個欄位的fieldSetting進去
但原本的fieldSettings有點大包餒
所以我們新增一個方法 傳入原本的fieldSettings以及電話元件的formGroup
吐我們需要的電話元件fieldSettings出來

    // 篩選組合元件用的setting
    getSettingsByForm(settings: FieldSetting[], fg: FormGroup): FieldSetting[]
    {
        return Object.keys(fg.value).map(v =>
        {
            return settings.find(setting => setting.groupType === v) as FieldSetting;
        })
    }

然後我們就得到了我們想要的兩個東西
只有電話三個欄位的fieldSettings以及formGroup
傳進這次的元件裡面

// form-input.component.html
        <app-combo-phone
          [fieldSettings]="
            getSettingsByForm(pageSetting.fieldSettings, fieldObj)
          "
          [inputForm]="fieldObj"
        >
        </app-combo-phone>

元件的部分
基本上因為電話說不定會有很多組
所以不能用name去指定組合電話元件內的位置
這邊我們會依照groupType去指定這三個欄位在元件裡的對應位置
所以這邊也增加一個方法去從fieldSetting取得groupType對應的設定
然後再透過這個設定檔的name去取得Control

// combo-phone.component.ts
    // 用name取得setting
    getSettingByGroupType(fieldSetting: any, groupType: string)
    {
        return fieldSetting.find((obj: any) => obj.groupType == groupType) || { cname: '', name: '', inputType: '' }
    }
    getControl(group: FormGroup, name: string)
    {
        return group?.get(name) as FormControl
    }
    
// combo-phone.component.html
    <div>
  <div class="row">
    <span>
      {{ getSettingByGroupType("phone-number").cname }}
    </span>
    <div class="col-3">
      <app-base-tel
        [fieldSetting]="getSettingByGroupType('phone-area')"
        [control]="getControl(inputForm, 'phone-area')"
      ></app-base-tel>
    </div>
    -
    <div class="col-4">
      <app-base-tel
        [fieldSetting]="getSettingByGroupType('phone-number')"
        [control]="getControl(inputForm, 'phone-number')"
      ></app-base-tel>
    </div>
    #
    <div class="col-4">
      <app-base-tel
        [fieldSetting]="getSettingByGroupType('phone-ext')"
        [control]="getControl(inputForm, 'phone-ext')"
      ></app-base-tel>
    </div>
  </div>
</div>

改到這邊
畫面稍微有點正常了https://ithelp.ithome.com.tw/upload/images/20241001/20168302uKeF2ZZxPe.png

不過換頁好像會有點問題 我們明天繼續處理

今日程式:day18


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

尚未有邦友留言

立即登入留言