跳到內容
+

Crud

Crud 元件提供使用者介面,以與來自任何資料來源的資料互動。

透過 Crud 元件及其子元件,您可以輕鬆產生頁面,在這些頁面中,可以表格形式列出、個別顯示詳細資訊,或使用表單建立和編輯來自資料來源的項目。所有這些都只需從單一資料來源定義進行最少的設定。

Demo

Crud 元件會自動為您的資料來源產生 CRUD 頁面,並自動與您的路由解決方案整合。所有需要做的就是 dataSource 定義和 CRUD 頁面的 rootPath

按下 Enter 開始編輯

頁面位於以下路由中

  • 列表/${rootPath}
  • 顯示/${rootPath}/:id
  • 建立/${rootPath}/new
  • 編輯/${rootPath}/:id/edit

這些預設路徑和其他開箱即用的設定可以被覆寫,並透過遵循下方的進階設定進行更詳細的配置。

建議包含 dataSourceCache 屬性,以便正確快取來自資料來源查詢方法的結果。請參閱下方關於資料快取章節以了解更多資訊。

或者,可以提供其他配置選項,例如用於分頁項目列表的 initialPageSize,或用於在使用表單建立新項目時設定初始表單值的 defaultValues

資料來源

資料來源是一個具有特定形狀的物件,必須用於配置 Crud 元件或其子元件。它包含

  • 一個 fields 屬性,它擴展了 Data Grid 欄位定義,您可以在其中為您的資料指定不同的欄位、標題名稱和欄位類型等等。id 欄位(字串或數字)是強制性的,以便可以識別個別項目。

  • 用於與資料互動的方法的屬性,例如 getManygetOnecreateOneupdateOnedeleteOne

  • 一個 validate 函數,用於在建立或編輯資料時進行表單驗證,它會為每個欄位傳回驗證錯誤。

以下是一個簡化的資料來源定義範例

const notesDataSource: DataSource<Note> = {
  fields: [
    { field: 'id', headerName: 'ID' },
    { field: 'title', headerName: 'Title' },
    { field: 'text', headerName: 'Text' },
  ],
  getMany: ({ paginationModel }) => {
    const start = paginationModel.page * paginationModel.pageSize;
    const end = start + paginationModel.pageSize;
    const paginatedNotes = notesStore.slice(start, end);

    return {
      items: paginatedNotes,
      itemCount: notesStore.length,
    };
  },
  getOne: (noteId) => {
    return notesStore.find((note) => note.id === noteId) ?? null;
  },
  createOne: (data) => {
    const newNote = { id: notesStore.length + 1, ...data } as Note;

    notesStore = [...notesStore, newNote];

    return newNote;
  },
  updateOne: (noteId, data) => {
    let updatedNote: Note | null = null;

    notesStore = notesStore.map((note) => {
      if (note.id === noteId) {
        updatedNote = { ...note, ...data };
        return updatedNote;
      }
      return note;
    });

    return updatedNote;
  },
  deleteOne: (noteId) => {
    notesStore = notesStore.filter((note) => note.id !== noteId);
  },
  validate: (formValues) => {
    let issues: { message: string; path: [keyof Note] }[] = [];

    if (!formValues.title) {
      issues = [...issues, { message: 'Title is required', path: ['title'] }];
    }
    if (!formValues.text) {
      issues = [...issues, { message: 'Text is required', path: ['text'] }];
    }

    return { issues };
  },
};

getMany

資料來源中的 getMany 方法可以用於檢索分頁、排序和篩選的項目,以便作為列表顯示,通常在表格中。

分頁、排序和篩選可以透過 paginationModelfilterModelsortModel 參數與您的資料獲取整合。這些參數遵循與 Data Grid 使用的分頁排序篩選模型相同的形狀。

此方法必須傳回一個物件陣列,其中包含要顯示的項目。

{
  //...
  getMany: async ({ paginationModel, filterModel, sortModel }) => {
    // Fetch data from server
    const data = await fetch('https://my-api.com/data', {
      method: 'GET',
      body: JSON.stringify({
        page: paginationModel.page,
        pageSize: paginationModel.pageSize,
        sortModel,
        filterModel,
      }),
    });

    return data
  },
  // ...
}

getOne

資料來源中的 getOne 方法可以用於檢索單一特定項目並顯示其所有屬性。

此方法必須傳回一個對應於要顯示項目的物件。

{
  //...
  getOne: async (id) => {
    // Fetch record from server
    const record = await fetch(`https://my-api.com/data/${id}`, {
      method: 'GET',
    });

    return record;
  },
  // ...
}

createOne

資料來源中的 createOne 方法可以用於建立新項目,通常是透過表單,在表單中可以指定其每個屬性的值。

此方法必須傳回一個對應於已建立新項目的物件。

{
  //...
  createOne: async (data) => {
    // Create record in the server
    const record = await fetch('https://my-api.com/data', {
      method: 'POST',
      body: JSON.stringify(data),
    });

    return record;
  },
  // ...
}

updateOne

資料來源中的 updateOne 方法可以用於更新現有項目,通常是透過表單,在表單中可以指定其每個屬性的值。

此方法必須傳回一個對應於已更新新項目的物件。

{
  //...
  updateOne: async (id, data) => {
    // Update record in the server
    const record = await fetch(`https://my-api.com/data/${id}`, {
      method: 'PUT',
      body: JSON.stringify(data),
    });

    return record;
  },
  // ...
}

deleteOne

資料來源中的 deleteOne 方法可以用於刪除現有項目。

此方法不需要傳回任何內容。

{
  //...
  deleteOne: async (id) => {
    // Delete record in the server
    await fetch(`https://my-api.com/data/${id}`, {
      method: 'DELETE',
    });
  },
  // ...
}

表單驗證

或者,可以在資料來源中包含 validate 函數,以便進行表單驗證。

此函數遵循 Standard Schema,因此它接受一個包含給定項目欄位值的物件,並且必須傳回每個欄位的相應錯誤,如範例所示

{
  //...
  validate: (formValues) => {
    let issues = [];

    if (!formValues.name) {
      issues = [...issues, { message: 'Name is required', path: ['name'] }];
    }
    if (formValues.age < 18) {
      issues = [...issues, { message: 'Age must be higher than 18', path: ['age'] }];
    }

    return { issues };
  },
  // ...
}

當使用者嘗試在 Crud 元件內提交表單或變更其任何欄位時,此函數會自動針對目前的值執行。

與外部 Schema 函式庫整合

validate 函數可以輕鬆地與任何遵循 Standard Schema 規格的 schema 函式庫整合,例如 zod

以下是使用 zod 的範例

import { z } from 'zod';

const dataSource = {
  // ...
  validate: z.object({
    name: z
      .string({ required_error: 'Name is required' })
      .nonempty('Name is required'),
    age: z
      .number({ required_error: 'Age is required' })
      .min(18, 'Age must be higher than 18'),
  })['~standard'].validate,
  // ...
};

資料快取

資料來源預設會快取已獲取的資料。這表示如果使用者查詢已獲取的資料,則不會再次呼叫 getManygetOne 等查詢方法,以避免對伺服器進行不必要的呼叫。

成功呼叫 createOneupdateOnedeleteOne 等變更方法會自動清除同一個資料來源中所有查詢的快取。

建議始終包含 dataSourceCache 屬性,以便在整個應用程式的範圍內快取資料,否則預設情況下,快取僅限於正在使用的元件的範圍。每個資料來源應該在整個應用程式中擁有自己的單一快取實例。

DataSourceCache 的實例可以用於快取,如上面的 demo 所示。DataSourceCache 是一個簡單的記憶體內快取,它將資料儲存在純物件中。

停用快取

若要停用資料來源快取,請將 null 傳遞給 dataSourceCache 屬性。

按下 Enter 開始編輯

進階設定

為了獲得更大的自訂彈性,特別是如果您想要完全控制不同 CRUD 頁面的放置位置,您可以使用 ListShowCreateEdit 子元件,而不是all-in-one 的 Crud 元件。

按下 Enter 開始編輯

CrudProvider 元件是選用的,但可以用於輕鬆地將單一 dataSourcedataSourceCache 作為上下文傳遞給其中的 CRUD 子元件。或者,這些元件中的每一個都可以將自己的 dataSourcedataSourceCache 作為 props。

List 元件

顯示一個 Data Grid,列出資料來源中的項目,並支援分頁、排序和篩選,以及一些有用的控制項,例如重新整理資料。

如果為 onCreateClickonEditClick 傳遞了 props,則會顯示用於觸發這些回呼的按鈕。

如果資料來源包含 deleteOne,則可以直接從其各自的列中刪除項目。

按下 Enter 開始編輯

與 Data Grid 整合

dataGrid slot 和 slot props 可以用於將標準 Data Grid 替換為其任何 商業授權版本

按下 Enter 開始編輯

Show 元件

顯示從資料來源檢索的具有給定 id 的項目的詳細資訊。

如果為 onEditClick 傳遞了 prop,則會顯示一個用於觸發該回呼的按鈕。

如果資料來源包含 deleteOne,則可以直接從此視圖中刪除項目。

按下 Enter 開始編輯

Create 元件

顯示一個表單,用於為資料來源建立新項目,該表單會根據給定的 fields 和欄位 type 自動產生。

支援的欄位類型為 stringnumberbooleandatedateTimesingleSelect

表單驗證會自動與資料來源中的 validate 函數整合。

按下 Enter 開始編輯

Edit 元件

顯示一個表單,用於編輯從資料來源檢索的具有給定 id 的項目,與 Create 元件類似。

表單欄位會預先填入項目的屬性。

按下 Enter 開始編輯

API

請參閱下方文件,以取得此處提及的元件可用的所有 props 和 classes 的完整參考。