You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在循环中使用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>

问题根源

  1. checked绑定逻辑错误:当前data-wp-bind--checked="state.chosen"是把state值直接转为布尔值(非零整数都会转为true),导致所有单选按钮被标记为checked。而浏览器对同name的单选按钮组只会保留最后一个选中状态,所以初始显示最后一个按钮选中。
  2. 点击后状态同步异常:点击时state更新为对应选项值,但checked绑定依然将state值转为true,所有radio仍被标记为checked,浏览器再次保留最后一个选中状态,导致视觉上选中状态未变化;第二次点击时浏览器触发默认单选选中逻辑,才显示正确状态。
  3. 类型差异影响:单选按钮的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:51:18