WP DEVELOP

EP097. “新笔记真实数据渲染与事件委托修复”

首页 WordPress 开发课程 MY NOTES 前端功能 · EP097
约 11 分钟· #EP097#MY NOTES 前端功能
🔒 登录后可标记已读

接上一讲,做两件收尾工作:① 把新建笔记时的占位文字 imagine real data here 换成用 REST API 响应里的真实数据(ID、标题、正文)拼出跟其他笔记完全一致的 HTML 结构;② 修复「新建出来的笔记,编辑/删除按钮点了没反应」的问题——原因是这些按钮是页面加载完之后才动态插入的,而最初的事件绑定方式只对页面加载时就存在的元素生效,需要改成事件委托(event delegation)写法


涉及文件

  • wp-content/themes/fictional-university-theme/src/modules/MyNotes.js (修改)

代码实现

events():把三个针对列表内按钮的绑定,从「直接绑定」改成「委托给外层容器」

// wp-content/themes/fictional-university-theme/src/modules/MyNotes.js

events() {
  $("#my-notes").on("click", ".delete-note", this.deleteNote)
  $("#my-notes").on("click", ".edit-note", this.editNote.bind(this))
  $("#my-notes").on("click", ".update-note", this.updateNote.bind(this))
  $(".submit-note").on("click", this.createNote.bind(this)) // 新建表单是固定不变的,不需要委托
}

createNote()success 回调里用模板字符串拼出跟真实笔记一致的 HTML

// wp-content/themes/fictional-university-theme/src/modules/MyNotes.js

success: response => {
  $(".new-note-title, .new-note-body").val("")
  $(`
    <li data-id="${response.id}">
      <input readonly class="note-title-field" value="${response.title.raw}">
      <span class="edit-note"><i class="fa fa-pencil" aria-hidden="true"></i> Edit</span>
      <span class="delete-note"><i class="fa fa-trash-o" aria-hidden="true"></i> Delete</span>
      <textarea readonly class="note-body-field">${response.content.raw}</textarea>
      <span class="update-note btn btn--blue btn--small"><i class="fa fa-arrow-right" aria-hidden="true"></i> Save</span>
    </li>
    `)
    .hide()
    .prependTo("#my-notes")
    .slideDown()
  console.log("Congrats")
  console.log(response)
}

关键改动点:

  • 事件委托写法:$("#my-notes").on("click", ".delete-note", callback) 跟直接绑定 $(".delete-note").on("click", callback) 的区别是——监听器实际挂在外层容器 #my-notes(这个元素页面加载时就存在,不会变),第二个参数 .delete-note 是一个「筛选条件」,意思是「只要点击事件冒泡到 #my-notes 时,实际点击的元素匹配这个选择器,才执行回调」。这样不管 .delete-note 元素是页面加载时就有的,还是之后动态插入的,都能被正确响应,因为判断是点击发生的那一刻才做的,不是绑定的那一刻
  • .submit-note(新建表单的提交按钮)不需要用委托写法,因为这个按钮从页面加载起就一直存在、不会被动态创建,直接绑定即可
  • 新建成功后的 HTML 结构直接复制自 page-my-notes.php 里已有的笔记条目模板,字段来源全部换成 response(WordPress REST API 创建成功后,会把新文章的完整数据回传回来):response.id 对应 data-idresponse.title.raw / response.content.raw 对应标题和正文——.raw 是因为 REST API 的标题/正文字段底下有 raw(原始未渲染内容)和 rendered(渲染后的 HTML)两个子属性,这里要的是原始文字,不是渲染过的 HTML
  • 新插入的 <li> 结构跟 page-my-notes.php 里 PHP 生成的完全一致(readonly 属性、note-title-field/note-body-field 等 class 名都对齐),这样它才能被前面改造过的事件委托正确识别、之后的编辑/删除/保存操作才能对它生效

[截图:前台新建笔记后,用服务器真实数据渲染出的新笔记条目,样式跟其他已有笔记完全一致]


Hook / Function 速查

名称类型用途
.on(event, selector, handler)jQuery 方法(事件委托写法)把事件监听器挂在稳定存在的祖先元素上,用选择器筛选实际触发的子元素,对动态插入的元素依然有效
REST API 响应里的 .raw / .renderedWP REST API 响应字段结构raw 是数据库原始内容,rendered 是转换成最终 HTML 后的内容,按需选用

常见坑

  • $(".edit-note").on("click", ...) 这种直接绑定方式处理「可能动态新增」的元素——只对绑定那一刻已存在于页面上的元素生效,之后新插入的同类元素不会有反应,必须改成挂在稳定外层容器上的事件委托写法
  • 混淆 response.title.rawresponse.title.rendered——两者都能读到标题文字,但语义不同,rendered 已经过 WordPress 处理(可能包含转义后的 HTML 实体),这里要的是干净的原始文字,用 raw

延伸 / 后续讲座会用到

到这里 CRUD 四个操作在前端全部跑通,但目前只有 Administrator/Editor 账号能创建笔记(因为 note 文章类型的默认权限还是继承自更高权限角色)。下一讲要给 Subscriber 角色开放创建/编辑/删除私人笔记的权限,同时要注意别因此破坏网站的安全性。


Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 19, EP097