在 WP 编辑器中获取 Combobox select 的值

Get the value of a Combobox select in WP editor

在 Wordpress 安装中,我有一个自定义 post 类型和一个带有自定义 post_meta 字段的元数据框。

Gutenberg 侧边栏中的

Parent 下拉字段曾经是 <select> 元素。我有一些脚本 onChange 触发不同字段的 hide/show 使它们成为条件,具体取决于正在编辑的页面是 parent 还是 child:

$(document).on("change", ".editor-page-attributes__parent select", function(){
    toggleFields();
}

<select> 中的选项将 ID 作为值,因此我可以获得 selected parent 的标题和 ID,并在 metabox 中为我的用户动态显示一些数据:

var dropdown = $('.editor-page-attributes__parent select');
var parentName = dropdown.find(':selected').text();
var parentId = dropdown.val();

自 v5.6 起,Wordpress 已将 select 元素替换为 Combo Box。我曾尝试获取相同的数据 onChange,但仅使用 blur:

取得了一些成功
$(document).on("blur", ".editor-page-attributes__parent .components-combobox-control__input", function(){
    toggleFields();
    var parentName = dropdown.val();
})

我只能获取页面标题,因为此组合框现在有一个缺少 ID 的输入元素,例如:

<input id="components-form-token-input-0" type="text" class="components-combobox-control__input components-form-token-field__input" value="Page Name Here">

我也尝试过 Ajax,以使用 get_page_by_title() 检索 ID,但它并不总是有效,因为页面可能具有相同的标题,编辑器还会在名称中添加破折号和空格层级。

如何在 Parent 组合框中获取更改时 select 页面的关联 ID?

阅读 Editor Documentation 一段时间后,我找到了正确的解决方案。这是您可以在 WP 编辑器中收听更改并获取父组合框 select 的 ID 的方法:

wp.data.subscribe( function () {
  var newParent = wp.data.select('core/editor').getEditedPostAttribute('parent');
  console.log(newParent);
} );

wp.data.subscribe在编辑器中编辑posts时,每次当前状态发生变化时都会调用,所以每次都会调用监听函数。当我们想要的字段发生实际更改时,我们可以通过简单的变量检查来避免这种情况。 It behaves as Redux subscribe 没有取消订阅,只有一个听众。

要同时检查我们正在编辑的当前 post 类型,我们可以使用 getCurrentPostType:

wp.data.select('core/editor').getCurrentPostType();

这是此问题的完整代码以供将来参考:

if (wp.data.select('core/editor').getCurrentPostType() == 'cpt_name') {
 const getPostParent = () => wp.data.select('core/editor').getEditedPostAttribute('parent');

 // set initial parent
 let postParent = getPostParent();

 wp.data.subscribe(() => {

    // get current parent
    const newPostParent = getPostParent();    

    // only if parent changes
    if( postParent !== newPostParent ) {
      // Do what we want after parent changed
         toggleFields();
    }

    // update the variable
    postParent = newPostParent;

 });

}