Polymer 1.*:dom-repeat内paper-radio-group初始化时无法查询元素
问题分析与解决方案
在Polymer 1.x里遇到这个问题,核心原因是**dom-repeat的DOM渲染是异步的**——它不会在组件初始化或数据绑定后立刻生成对应的DOM元素。
你说addFormData能正常查询到元素,是因为用户填写表单时,dom-repeat早就完成了异步渲染流程;而首次加载时调用setRadioDefaults,不管是直接在ready/attached钩子中调用,还是用短时长的setTimeout,都赶在dom-repeat渲染完成之前,所以拿到的节点列表是空的。哪怕你延长setTimeout的时间,也不是可靠的方案,因为不同设备、场景下的渲染耗时差异很大。
靠谱的解决方法:监听dom-repeat的dom-change事件
dom-repeat组件自带dom-change事件,这个事件会在它完成DOM渲染(包括首次渲染、数据更新后的重新渲染)之后触发,这是最准确的时机。
具体实现步骤:
- 在你的
dom-repeat模板上添加on-dom-change事件绑定:
<template is="dom-repeat" items="{{yourDataList}}" on-dom-change="onDomRepeatRendered"> <paper-radio-group name$="{{item.groupName}}"> <!-- 你的paper-radio-button元素 --> </paper-radio-group> </template>
- 在组件脚本中实现事件处理函数,在里面调用你的
setRadioDefaults:
onDomRepeatRendered: function() { // 此时dom-repeat已经完成渲染,可以安全查询元素 this.setRadioDefaults(); }, setRadioDefaults: function() { const radioGroups = this.querySelectorAll('paper-radio-group'); if (radioGroups.length > 0) { // 遍历设置默认值,比如根据你的数据给指定group设置选中项 radioGroups.forEach(group => { // 假设你的默认值存在对应的数据里,比如group.name对应的defaultValue const defaultValue = this.getRadioDefault(group.name); if (defaultValue) { group.selected = defaultValue; } }); } }
额外注意点
如果你的yourDataList是通过异步请求获取的(比如iron-ajax),不用担心,dom-change会在数据加载完成、dom-repeat重新渲染后再次触发,确保你能拿到最新的DOM元素。
内容的提问来源于stack exchange,提问作者dman
相关产品推荐
相关产品推荐

