跳轉到

什麼是外掛欄位?

外掛欄位是 UOF X BPM 表單中的自訂欄位類型,讓您建立符合特殊需求的表單欄位。

本頁面說明外掛欄位專案的基本架構,以及如何建立和設定外掛欄位的檔案結構。

外掛欄位在表單設計器中的顯示

外掛欄位在 BPM 表單設計器中的顯示

專案架構概覽

基本的網站原始碼皆放置在 Ede.Uofx.Customize.Web 內:

外掛專案目錄結構
├─ ClientApp (前端 Angular)
│  ├─ src
│  │  ├─ app
│  │  │  ├─ mobile (放置手機版內容)
│  │  │  ├─ service (基礎發送至後端 API 請求服務)
│  │  │  ├─ shared (放置共用內容,如:Props 模型)
│  │  │  ├─ web (放置網頁版內容)
│  │  │  └─ app.module.ts
│  │  ├─ assets
│  │  │  └─ configs (⚙️ 設定檔目錄)
│  │  │     ├─ fields-design.json     # 設定欄位樣式
│  │  │     ├─ fields-runtime.json    # 設定欄位執行時使用的程式
│  │  │     └─ routes.json            # 設定各端的外掛頁面選單
│  │  └─ plugin.manifest.json         # 模組套件配置檔
│  └─ webpack-exposes.config.js        # 設定前端 Module 建構後的別名
└─ Controllers (🔧 後端 API)

外掛欄位顯示模式

外掛欄位在不同的使用情境下會有不同的顯示模式,每種模式都有其特定的用途和檔案結構。

模式概覽

模式 使用時機 檔案位置 必要性
Design 表單設計時 src/app/web/advanced-field/design ⭕ 可選
Props 屬性設定時 src/app/web/advanced-field/props ✅ 必要
Write 填寫表單時 src/app/web/advanced-field/write ✅ 必要
View 觀看表單時 src/app/web/advanced-field/view ⭕ 可選
Print 列印表單時 src/app/web/advanced-field/print ⭕ 可選

外掛欄位檔案結構

Web 外掛欄位目錄結構

實作 Web 外掛欄位時,請參考範例專案中的 src/app/web/advanced-field 檔案結構:

參考檔案: advanced-field 目錄結構

Web 外掛欄位目錄結構
src/app/web/advanced-field/
├─ design/                    # 設計模式 Component (可選)
│  ├─ design.component.ts
│  ├─ design.component.html
│  └─ design.component.scss
├─ props/                     # 屬性設定 Component  
│  ├─ props.component.ts
│  ├─ props.component.html
│  └─ props.component.scss
├─ write/                     # 填寫模式 Component
│  ├─ write.component.ts
│  ├─ write.component.html
│  └─ write.component.scss
├─ view/                      # 觀看模式 Component (可選)
│  ├─ view.component.ts
│  ├─ view.component.html
│  └─ view.component.scss
├─ print/                     # 列印模式 Component (可選)
│  ├─ print.component.ts
│  ├─ print.component.html
│  └─ print.component.scss
└─ advanced-field.module.ts

Web 外掛欄位模組設定

參考檔案: advanced-field.module.ts

advanced-field.module.ts (Web)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';

// 匯入各種模式的 Component
import { AdvancedFieldDesignComponent } from './design/design.component';
import { AdvancedFieldPropsComponent } from './props/props.component';
import { AdvancedFieldWriteComponent } from './write/write.component';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    RouterModule.forChild([
      { path: '', redirectTo: 'design', pathMatch: 'full' },
      { path: 'design', component: AdvancedFieldDesignComponent },
      { path: 'props', component: AdvancedFieldPropsComponent },
      { path: 'write', component: AdvancedFieldWriteComponent },
      { path: 'view', component: AdvancedFieldWriteComponent },
    ]),
    TranslateModule.forChild(),
    ...PRIMENG_MODULES,
    ...UOF_MODULES
  ],
  providers: [
    UofxPluginApiService,
    NorthWindService,
    SdkService,
    UofxFilePluginService,
    UofxUserSetPluginHelper,
    UofxUserSetPluginService,
    ...EMP_SERVICES
  ],
  exports: [...COMPONENTS],
  declarations: [...COMPONENTS]
})

export class AdvancedFieldModule {
  static comp = {
    props: AdvancedFieldPropsComponent,
    design: AdvancedFieldDesignComponent,
    write: AdvancedFieldWriteComponent,
    view: AdvancedFieldWriteComponent,
    print: AdvancedFieldWriteComponent,
  }
}

開發建議

最少需要實作: Props + Write 兩種模式

Design、View 和 Print 模式:

方案一:使用 Write 模式統一處理

  • 如未實作,在 advanced-field.module.ts 設定時可填上 write
  • 在 Write 模式中透過 this.editable 來切換內容是否可編輯

方案二:分別實作不同模式

  • 適用情境: 各種模式需要不同的 UI 樣式或顯示邏輯
  • 優點: 關注點分離,每種模式專注於自己的 UI 變化
advanced-field.module.ts - 方案一:統一使用 Write 模式
export class AdvancedFieldModule {
    static comp = {
        props: AdvancedFieldPropsComponent,
        design: AdvancedFieldWriteComponent,    // 使用 Write 模式
        write: AdvancedFieldWriteComponent,
        view: AdvancedFieldWriteComponent,      // 使用 Write 模式
        print: AdvancedFieldWriteComponent,     // 使用 Write 模式
    }
}
advanced-field.module.ts - 方案二:分別實作各種模式
export class AdvancedFieldModule {
    static comp = {
        props: AdvancedFieldPropsComponent,
        design: AdvancedFieldDesignComponent,   // 專屬的設計模式 UI
        write: AdvancedFieldWriteComponent,
        view: AdvancedFieldViewComponent,       // 專屬的觀看模式 UI
        print: AdvancedFieldPrintComponent,     // 專屬的列印模式 UI
    }
}

APP 外掛欄位目錄結構

實作 APP 外掛欄位時,請參考範例專案中的 src/app/mobile/advanced-field 檔案結構:

參考檔案: advanced-field 目錄結構

APP 外掛欄位目錄結構
src/app/mobile/advanced-field/
├─ write/                        # 填寫模式 Component  
│  ├─ write.component.ts
│  ├─ write.component.html
│  └─ write.component.scss
└─ advanced-field.module.ts

APP 外掛欄位模組設定

參考檔案: advanced-field.module.ts

advanced-field.module.ts (APP)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { IonicModule } from '@ionic/angular';

// 匯入各種模式的 Component
import { AdvancedFieldComponent } from './advanced-field.component';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    RouterModule.forChild([
      { path: '', component: AdvancedFieldComponent, pathMatch: 'full' }
    ]),
    IonicModule.forRoot(),
    ...UOF_MODULES
  ],
  providers: [
    UofxPluginApiService,
    { provide: BASIC_HTTP_HANDLER, useClass: MyHttpHandler },
    BasicHttpClient,
    EmployeeService,
    UofxUserSetPluginHelper,
  ],
  exports: [...COMPONENTS],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  declarations: [...COMPONENTS]
})
export class FieldAdvancedAppModule {
  static comp = {
    write: AdvancedFieldComponent,
    view: AdvancedFieldComponent
  }
}

下一步

開始實作您的第一個外掛欄位

已經了解外掛欄位架構?準備開始撰寫程式碼!

開始實作外掛欄位

探索其他

回到開發地圖