iT邦幫忙

2024 iThome 鐵人賽

DAY 14
0

昨天加上了檢核的部分
要讓檢核能更方便的應用
那應該得做一下分頁的部分
畢竟我們想要用設定檔產生畫面
一些頁面上的基本設定也可以在分頁設定檔上使用

首先我們做個簡單的重構
多增加一層處理form邏輯的form-input.component
一樣是在element資料夾下

ng g component form-input

然後把main的邏輯搬遷到新的form-input之下

// form-input.component.ts
import { Component, Input, OnChanges, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { PageSetting } from '../field-setting.model';

@Component({
    selector: 'app-form-input',
    templateUrl: './form-input.component.html',
    styleUrls: ['./form-input.component.scss']
})
export class FormInputComponent implements OnChanges
{
    @Input() pageSetting!: PageSetting
    fieldObj!: object;
    constructor(private fb: FormBuilder) { }

    ngOnChanges(): void
    {
        // 用reduce將name作為key值 defaultValue作為Value

        this.pageSetting.form = this.fb.group(this.pageSetting.fieldSettings.reduce((acc: any, item) =>
        {
            acc[item.name] = [item.defaultValue || ''];
            if (item.validator && item.validator.length > 0)
            {
                acc[item.name].push({ validators: item.validator })
            }
            return acc;
        }, {}));
        console.log('pageSetting', this.pageSetting)
    }

    getControl(columnName: string)
    {
        return this.pageSetting.form?.get(columnName) as FormControl
    }

}

// form-input.component.html
<div [formGroup]="pageSetting.form!" *ngIf="pageSetting.form">
  {{ pageSetting.title }}
  <div *ngFor="let fieldSetting of pageSetting.fieldSettings">
    <app-field-template
      [fieldSetting]="fieldSetting"
      [control]="getControl(fieldSetting.name)"
    >
    </app-field-template>
    <!-- {{ getControl(fieldSetting.name).value }} -->
  </div>
</div>

main的頁面也跟著調整
這邊另外先增加一個pageSetting的interface
這是頁面相關的設定

export interface PageSetting
{
    title: string;
    form?: FormGroup;
    fieldSettings: FieldSetting[];
}

調整後的main

import { Component, OnInit } from '@angular/core';
import { Validators } from '@angular/forms';
import { PageSetting } from 'src/app/shared/component/form/element/field-setting.model';

@Component({
    selector: 'app-main',
    templateUrl: './main.component.html',
    styleUrls: ['./main.component.scss']
})
export class MainComponent implements OnInit
{
    page = 0;
    pageSettings: PageSetting[] = [{
        title: '第一頁',
        fieldSettings: [
            {
                name: 'text1',
                cname: '文字欄位1',
                inputType: 'text',
                placeholder: '請輸入文字',
                required: true,
                defaultValue: '123',
                validator: [Validators.required, Validators.maxLength(10)]
            },
            {
                name: 'number1',
                cname: '數字欄位',
                inputType: 'number',
                placeholder: '請輸入數字',
                required: true,
                defaultValue: '123'
            },
            {
                name: 'tel1',
                cname: '電話欄位1',
                inputType: 'tel',
                placeholder: '請輸入',
                required: true,
            },
            {
                name: 'password1',
                cname: '密碼欄位1',
                inputType: 'password',
                placeholder: '請輸入',
                required: true,
            },
            {
                name: 'select1',
                cname: '下拉選單1',
                inputType: 'select',
                placeholder: '請選擇',
                required: true,
                defaultValue: '1',
                options: [
                    { label: '選項1', value: '1' },
                    { label: '選項2', value: '2' },
                    { label: '選項3', value: '3' },
                ]
            },
            {
                name: 'radio1',
                cname: '單選1',
                inputType: 'radio',
                placeholder: '',
                required: true,
                defaultValue: '1',
                options: [
                    { label: '選項1', value: '1' },
                    { label: '選項2', value: '2' },
                    { label: '選項3', value: '3' },
                ]
            },
            {
                name: 'checkbox1',
                cname: '多選1',
                inputType: 'checkbox',
                placeholder: '',
                required: true,
                defaultValue: '1,2',
                options: [
                    { label: '選項1', value: '1' },
                    { label: '選項2', value: '2' },
                    { label: '選項3', value: '3' },
                ]
            },
        ]
    }, {
        title: '第二頁',
        fieldSettings: [
            {
                name: 'text1',
                cname: '文字欄位1',
                inputType: 'text',
                placeholder: '請輸入文字',
                required: true,
                defaultValue: '123',
                validator: [Validators.required, Validators.maxLength(10)]
            },
            {
                name: 'number1',
                cname: '數字欄位',
                inputType: 'number',
                placeholder: '請輸入數字',
                required: true,
                defaultValue: '123'
            },
            {
                name: 'tel1',
                cname: '電話欄位1',
                inputType: 'tel',
                placeholder: '請輸入',
                required: true,
            },
            {
                name: 'password1',
                cname: '密碼欄位1',
                inputType: 'password',
                placeholder: '請輸入',
                required: true,
            },
        ]
    }, {
        title: '第三頁',
        fieldSettings: [
            {
                name: 'text1',
                cname: '文字欄位1',
                inputType: 'text',
                placeholder: '請輸入文字',
                required: true,
                defaultValue: '123',
                validator: [Validators.required, Validators.maxLength(10)]
            },
            {
                name: 'number1',
                cname: '數字欄位',
                inputType: 'number',
                placeholder: '請輸入數字',
                required: true,
                defaultValue: '123'
            },
            {
                name: 'tel1',
                cname: '電話欄位1',
                inputType: 'tel',
                placeholder: '請輸入',
                required: true,
            },
            {
                name: 'password1',
                cname: '密碼欄位1',
                inputType: 'password',
                placeholder: '請輸入',
                required: true,
            },
            {
                name: 'select1',
                cname: '下拉選單1',
                inputType: 'select',
                placeholder: '請選擇',
                required: true,
                defaultValue: '1',
                options: [
                    { label: '選項1', value: '1' },
                    { label: '選項2', value: '2' },
                    { label: '選項3', value: '3' },
                ]
            },
            {
                name: 'radio1',
                cname: '單選1',
                inputType: 'radio',
                placeholder: '',
                required: true,
                defaultValue: '1',
                options: [
                    { label: '選項1', value: '1' },
                    { label: '選項2', value: '2' },
                    { label: '選項3', value: '3' },
                ]
            },
            {
                name: 'checkbox1',
                cname: '多選1',
                inputType: 'checkbox',
                placeholder: '',
                required: true,
                defaultValue: '1,2',
                options: [
                    { label: '選項1', value: '1' },
                    { label: '選項2', value: '2' },
                    { label: '選項3', value: '3' },
                ]
            },
        ]
    }]


    constructor() { }

    ngOnInit(): void
    {
    }

    pageNext()
    {
        if (this.pageSettings[this.page].form?.invalid) return;
        if (this.page < this.pageSettings.length - 1)
        {
            this.page = Number(this.page) + 1;
        }
    }

    pagePrev()
    {
        if (this.page > 0)
            this.page = Number(this.page) - 1;
    }
}
// main.component.html
<div>
  <app-form-input [pageSetting]="pageSettings[page]"> </app-form-input>
  <button (click)="pagePrev()">上一頁</button>
  <button (click)="pageNext()">下一頁</button>
</div>

可以看到畫面上簡化了不少
設定檔的部份多了一層pageSettings
裡面是pageSetting構成的陣列
基本上這個陣列有幾個就可以產生幾頁
應用的地方用可以變數去控制分頁
main控制分頁變動決定傳到form-input的pageSetting是哪一個
裡面有title去控制表單開頭
以及傳fieldSetting進去產生表單
pageSetting有form但是不給初始值
初始化的部分在form-input的地方處理
form-input透過fieldSetting產生表單
並將產生出來的表單直接裝到pageSetting的form裡面
之後檢核會直接判斷pageSetting裡面的form
另外再加了上一頁下一頁的控制

分頁的部分就到這邊
明天再來調整檢核的部分

今日程式:day14


上一篇
第13天 validator檢核元件(下)
系列文
簡單的事 最困難-Angular動態Form元件14
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言