iT邦幫忙

2024 iThome 鐵人賽

DAY 21
0

之前做了兩個複合元件
今天要做一個很有機會用到的元件
就是地址元件
地址的話會需要選縣市
選完縣市以後會在選行政區
後面地址用文字輸入框
特別的地方就是行政區的下拉選單內容
取決於前面縣市的選項
會跟著前面選擇的縣市改變

那就開始今天的程式
一樣新增設定檔

  {
                name: 'addressCity',
                cname: '地址',
                inputType: 'select',
                groupName: 'address1',
                groupType: 'address-city',
                options: []
            },
            {
                name: 'addressArea',
                cname: '地址行政區',
                inputType: 'select',
                groupName: 'address1',
                groupType: 'address-area',
                options: []
            },
            {
                name: 'address',
                cname: '地址',
                inputType: 'text',
                groupName: 'address1',
                groupType: 'address',
                options: []
            },

我們需要兩個下拉選單以及一個輸入框
因為地址內選擇的部分應該是固定的
所以這邊應該會寫在元件裡面
接著新增combo-address.component

//combo-address.component.html
<div>
  <div class="row">
    <span>
      {{ getSettingByGroupType("address").cname }}
    </span>
    <div class="col-3">
      <app-field
        [fieldSetting]="getSettingByGroupType('address-city')"
        [control]="getControl(inputForm, 'address-city')"
      ></app-field>
    </div>
    <div class="col-4">
      <app-field
        [fieldSetting]="getSettingByGroupType('address-area')"
        [control]="getControl(inputForm, 'address-area')"
      ></app-field>
    </div>
    <div class="col-4">
      <app-field
        [fieldSetting]="getSettingByGroupType('address')"
        [control]="getControl(inputForm, 'address')"
      ></app-field>
    </div>
  </div>
</div>
//combo-address.component.ts    

    @Input() fieldSettings!: FieldSetting[];
    @Input() inputForm!: FormGroup;

    constructor(public shareService: ShareService) { }

    getControl(group: FormGroup, groupType: string): FormControl
    {
        return this.shareService.getControl(group, this.getSettingByGroupType(groupType).name);
    }

    // 用name取得setting
    getSettingByGroupType(groupType: string)
    {
        return this.shareService.getSetting(this.fieldSettings, groupType, 'groupType');
    }

受惠於昨天我們重構的關係 基本的部分根昨天元件差不多 調整groupType的部分
那這邊我們要多寫一段取得option的部分

    allOptions = [
    {
        "type": "CITY",
        "code": "A",
        "name": "台北市",
        "cityCode": "A"
    },
    {
        "type": "ZIP",
        "code": "100",
        "name": "中正區",
        "cityCode": "A"
    },

我們的縣市資料大概會是這樣
會有縣市 跟行政區的部分
縣市的code就是身分證上面第一個字的縣市代碼
行政區的code就是郵遞區號


    ngOnChanges(): void
    {
        let citySetting = this.getSettingByGroupType('address-city');
        citySetting.options = this.allOptions.filter((opt: any) => opt.type == "CITY").map(opt => { return { label: opt.name, value: opt.code } })
        let cityControl = this.getControl(this.inputForm, 'address-city') as FormControl;
        if (!!cityControl.value)
        {
            let areaSetting = this.getSettingByGroupType('address-area');
            areaSetting.options = this.allOptions.filter((opt: any) =>
            {
                return opt.type == "ZIP" && opt.cityCode == cityControl.value
            }).map(opt => { return { label: opt.name, value: opt.code } })
        }
    }

這邊一樣要注意我們要改成ngOnChanges
我們將allOptions過濾出type是CITY的
將結果傳到縣市的fieldSetting.option
然後如果縣市的control有值的時候
將allOptions過濾出type是ZIP以及cityCode為當前選擇CITY的資料
再將這個資料放到行政區的fieldSetting.option
然後別忘了調整combo-field-template裡面
添加判斷新的地址元件

  <div *ngIf="findFieldSetting('address')">
    <app-combo-address [fieldSettings]="fieldSettings" [inputForm]="inputForm">
    </app-combo-address>
  </div>

以上就是地址元件的部分 明天在繼續看看可以改什麼

今日程式:day21


上一篇
第20天 重構組合元件 及 組合元件radio+text
下一篇
第22天 mock-data
系列文
簡單的事 最困難-Angular動態Form元件30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言