第4部分:构建创建页面表单

上一部分我们创建了一个编辑页面功能,在本部分中,我们将添加一个创建页面功能。以下是我们将要构建的内容:

步骤1:添加“创建新页面”按钮

让我们首先构建一个按钮来显示创建页面形式。它类似于编辑按钮,我们在第3部分:

从“@wordpress/data”导入{useDispatch};从“@wordpress/components”导入{Button、Modal、TextControl};函数CreatePageButton(){const[isOpen,setOpen]=使用状态(false);const openModal=()=>设置打开(true);const closeModal=()=>设置打开(false);返回(<><Button onClick={openModal}variant=“primary”>创建新页面</按钮>{isOpen(打开)&&(<Modal onRequestClose={closeModal}title=“创建新页面”><创建页面表单onCancel={closeModal}onSaveFinished={closeModal}/></模式>) }</>);}函数CreatePageForm(){//现在是空的返回<div/>;}

伟大的!现在让我们我的第一个应用程序显示我们闪亮的新按钮:

函数MyFirstApp(){// ...返回(<div><div className=“list-controls”><SearchControl onChange={setSearchTerm}值={searchTerm}/><创建页面按钮/></div><PagesList hasResolved={hasResorved}pages={pages}/></div>);}

最终结果如下:

步骤2:提取受控PageForm

现在按钮已经就位,我们可以将注意力完全放在构建表单上了。本教程是关于管理数据的,所以我们不会构建完整的页面编辑器。相反,表单将只包含一个字段:文章标题。

幸运的是编辑页面表单我们建造了第三部分我们已经走了80%的路了。大部分用户界面已经可用,我们将在创建页面表单。让我们从将表单UI提取到单独的组件开始:

函数EditPageForm({pageId,onCancel,onSaveFinished}){// ...返回(<页面形式title={page.title}onChangeTitle={handleChange}hasEdits={hasEdits\}lastError={lastEror}isSaving={isSaving}onCancel={onCancel}onSave={handleSave}/>);}函数PageForm({title,onChangeTitle,hasEdits,lastError,isSaving,onCancel,onSave}){返回(<div className=“my-gutenberg-form”><文本控件label=“页面标题:”值={title}onChange={onChangeTitle}/>{last错误(错误:{lastError.message}) : () }<div className=“表单按钮”><按钮onClick={onSave}variant=“主要”disabled={!hasEdits|isSaving}>{正在保存吗(<><微调器/>正在保存</>):“保存”}</按钮><按钮onClick={onCancel}variant=“三级”disabled={isSaving}>取消</按钮></div></div>);}

此代码质量更改不应改变应用程序的工作方式。让我们尝试编辑页面以确保:

伟大的!编辑表单仍然存在,现在我们有了一个构建块来支持新的创建页面窗体.

步骤3:构建CreatePageForm

唯一一件事创建页面表单组件必须做的是提供呈现页面表单组件:

  • 标题
  • onChangeTitle(更改标题)
  • has编辑
  • last错误
  • 正在保存
  • onCancel(取消)
  • onSave(保存)

让我们看看如何做到这一点:

标题,onChangeTitle,hasEdits

这个编辑页面表单更新并保存了处于Redux状态的现有实体记录。因此,我们依靠编辑的实体记录选择器。

如果创建页面表单然而,没有预先存在的实体记录。只有一个空表单。用户键入的任何内容都是该表单的本地内容,这意味着我们可以使用React跟踪它使用状态挂钩:

函数CreatePageForm({onCancel,onSaveFinished}){const[title,setTitle]=useState();const-handleChange=(title)=>setTitle(标题);返回(<页面形式title={title}onChangeTitle={setTitle}hasEdits={!!title}{ /* ... */ }/>);}

onSave,onCancel

编辑页面窗体,我们发送了saveEditedEntityRecord('postType','page',pageId)保存处于Redux状态的编辑的操作。

创建页面表单然而,我们在Redux状态中没有任何编辑,也没有页面ID。在这种情况下,我们需要采取的行动称为保存实体记录(没有单词已编辑名称中),它接受表示新实体记录的对象,而不是页面ID.

传递给的数据保存实体记录通过POST请求发送到相应的REST API端点。例如,调度以下操作:

saveEntityRecord('postType','page',{title:“测试”});

触发对的POST请求/wp/v2/页WordPress REST API请求正文中具有单个字段的端点:title=测试.

现在我们了解了更多保存实体记录,让我们用它创建页面表单.

函数CreatePageForm({onSaveFinished,onCancel}){// ...const{saveEntityRecord}=useDispatch(coreDataStore);const-handleSave=async()=>{const savedRecord=等待saveEntityRecord(“postType”,'第页',{标题});if(保存的记录){onSaveFinished();}};返回(<页面形式{ /* ... */ }onSave={handleSave}onCancel={onCancel}/>);}

还有一个细节需要解决:我们新创建的页面尚未被页面列表。根据REST API文档/wp/v2/页端点创建(邮政请求)页面状态=草稿默认情况下,但收益(GET(获取)请求)页面status=发布解决方案是通过地位显式参数:

函数CreatePageForm({onSaveFinished,onCancel}){// ...const{saveEntityRecord}=useDispatch(核心数据存储);const-handleSave=async()=>{const savedRecord=等待saveEntityRecord(“postType”,'第页',{标题,状态:“发布”});if(保存的记录){onSaveFinished();}};返回(<页面形式{ /* ... */ }onSave={handleSave}onCancel={onCancel}/>);}

继续,并将此更改应用到您的本地创建页面表单组件,让我们处理剩下的两个道具。

last错误,正在保存

这个编辑页面表单通过检索错误和进度信息获取最后实体保存错误是保存实体记录选择器。在这两种情况下,它都传递了以下三个参数:(“postType”,“page”,pageId).

创建页面表单然而,我们没有页面ID.现在怎么办?我们可以跳过页面ID参数来检索有关没有任何id的实体记录的信息&这将是新创建的实体记录。这个使用选择因此,调用与来自编辑页面表单:

函数CreatePageForm({onCancel,onSaveFinished}){// ...const{lastError,isSaving}=useSelect((选择)=>({//请注意缺少pageId参数:lastError:选择(coreDataStore).getLastEntitySaveError(“postType”,“page”),//注意缺少pageId参数正在保存:选择(核心数据存储).isSavingEntityRecord(“postType”,“page”),} ),[]);// ...返回(<页面形式{ /* ... */ }lastError={lastEror}isSaving={isSaving}/>);}

就这样!下面是我们的新表单在实际操作中的外观:


将其连接在一起

以下是我们在本章中构建的所有内容:

函数CreatePageForm({onCancel,onSaveFinished}){const[title,setTitle]=useState();const{lastError,isSaving}=使用选择((选择)=>({lastError:选择(coreDataStore).getLastEntitySaveError(“postType”,“page”),正在保存:选择(核心数据存储).isSavingEntityRecord(“postType”,“page”),} ),[]);const{saveEntityRecord}=useDispatch(核心数据存储);const-handleSave=async()=>{const savedRecord=等待saveEntityRecord(“postType”,'第页',{标题,状态:“发布”});if(保存的记录){onSaveFinished()上;}};返回(<页面形式title={title}onChangeTitle={setTitle}hasEdits={!!title}onSave={handleSave}lastError={lastEror}onCancel={onCancel}isSaving={isSaving}/>);}函数EditPageForm({pageId,onCancel,onSaveFinished}){const{page,lastError,isSaving,hasEdits}=useSelect((选择)=>({页面:select(coreDataStore).getEditedEntityRecord('postType','page',pageId),lastError:选择(coreDataStore).getLastEntitySaveError(“postType”,“page”,pageId),isSaving:选择(coreDataStore).isSavingEntityRecord('postType','page',pageId),hasEdits:select(coreDataStore).hasEditsForEntityRecord('postType','page',pageId),} ),[页面ID]);const{saveEditedEntityRecord,editEntityRegord}=useDispatch(核心数据存储);const-handleSave=async()=>{const savedRecord=等待saveEditedEntityRecord(“postType”,“page”,pageId);if(保存的记录){onSaveFinished();}};const handleChange=(title)=>editEntityRecord('postType','page',page.id,{title});返回(<页面表单title={page.title}onChangeTitle={handleChange}hasEdits={hasEdits\}lastError={lastEror}isSaving={isSaving}onCancel={onCancel}onSave={handleSave}/>);}函数PageForm({title,onChangeTitle,hasEdits,lastError,isSaving,onCancel,onSave}){返回(<div className=“my-gutenberg-form”><文本控件label=“页面标题:”值={title}onChange={onChangeTitle}/>{lastError(错误:{lastError.message}) : () }<div className=“表单按钮”><按钮onClick={onSave}variant=“主要”disabled={!hasEdits|isSaving}>{正在保存吗(<><微调器/>正在保存</>):'保存'}</按钮><按钮onClick={onCancel}variant=“三级”disabled={isSaving}>取消</按钮></div></div>);}

剩下的就是刷新页面并享受表单:

接下来是什么?