如何在循环中使用WordPress Interactivity API绑定单选按钮checked状态?
问题:WordPress Interactivity API循环单选按钮绑定checked状态异常
问题描述
- 能否为循环生成的单选按钮组绑定
checked状态,由state控制? - 当前state值为2,但最后一个单选按钮被选中;点击选项时,state和文本输入框更新正常,但对应单选按钮需点击两次才显示选中(选择值2时除外)。
- 发现使用字符串(如'1')和整数(如1)时行为不同,疑惑是时序/重渲染问题还是bind功能不被支持,求解决方法。
原始代码
view.js
import { store, getContext } from '@wordpress/interactivity'; const { state } = store( 'example', { state: { answers: [ 1, 2, 3, 4 ], chosen: 2, }, actions: { handle: () => { const context = getContext(); console.log( context.answer ); state.chosen = context.answer; console.log( state ); }, }, } );
render.php
<div <?php echo get_block_wrapper_attributes(); ?> data-wp-interactive="example" <?php echo wp_interactivity_data_wp_context( array() ); ?>> <div> <template data-wp-each--answer="state.answers"> <input type="radio" data-wp-bind--checked="state.chosen" name="choice" data-wp-bind--value="context.answer" data-wp-on--click="actions.handle"> <label for="" data-wp-text="context.answer"> </label> </template> </div> <input data-wp-bind--value="state.chosen" type="text"> </div>
问题根源
- checked绑定逻辑错误:当前
data-wp-bind--checked="state.chosen"是把state值直接转为布尔值(非零整数都会转为true),导致所有单选按钮被标记为checked。而浏览器对同name的单选按钮组只会保留最后一个选中状态,所以初始显示最后一个按钮选中。 - 点击后状态同步异常:点击时state更新为对应选项值,但checked绑定依然将state值转为true,所有radio仍被标记为checked,浏览器再次保留最后一个选中状态,导致视觉上选中状态未变化;第二次点击时浏览器触发默认单选选中逻辑,才显示正确状态。
- 类型差异影响:单选按钮的
value在DOM中是字符串类型,若state中存储的是整数,直接赋值后虽能同步文本框,但错误的checked绑定逻辑会放大类型差异带来的问题。
修复方案
核心修改:修正checked绑定逻辑
将data-wp-bind--checked改为判断当前选项是否等于state中的选中值,而非直接绑定state值。
修改后的代码
view.js
import { store, getContext } from '@wordpress/interactivity'; const { state } = store( 'example', { state: { answers: [ 1, 2, 3, 4 ], // 保持整数或改为字符串数组都可,只需保证比较时类型一致 chosen: 2, }, actions: { handle: () => { const context = getContext(); state.chosen = context.answer; }, }, } );
render.php
<div <?php echo get_block_wrapper_attributes(); ?> data-wp-interactive="example" <?php echo wp_interactivity_data_wp_context( array() ); ?>> <div> <template data-wp-each--answer="state.answers"> <input type="radio" data-wp-bind--checked="state.chosen === context.answer" name="choice" data-wp-bind--value="context.answer" data-wp-on--click="actions.handle" > <label data-wp-text="context.answer"></label> </template> </div> <input data-wp-bind--value="state.chosen" type="text"> </div>
可选优化:统一值类型(避免隐式转换)
如果担心类型问题,可将state中的值统一为字符串类型:
// view.js中修改state state: { answers: [ '1', '2', '3', '4' ], chosen: '2', },
内容的提问来源于stack exchange,提问作者Webconstructor
相关产品推荐
相关产品推荐

