Polymer 1.* IronValidatableBehavior回调setInvalidStates作用域问题求助
解决Polymer 1.x中回调函数作用域与参数undefined问题
首先,咱们先明确问题根源:当你把父元素的this.setInvalidStates作为参数传递给子元素的checkIfDateHasValue时,要么是函数上下文丢失导致方法无法正确指向父元素,要么是传递方式不对导致参数没被正确传入,最终出现setInvalidStates为undefined的情况。下面给你几种靠谱的修复方案,按推荐程度排序:
方案1:用事件驱动替代直接传回调(最符合Polymer设计模式)
Polymer组件间通信更推荐事件触发的方式,完全规避作用域问题,还能让组件解耦:
子元素(birthdate)代码
Polymer({ is: 'birthdate', checkIfDateHasValue() { // 模拟日期有效性检查逻辑 const dateHasValue = this.$.dateInput.value.trim() !== ''; // 触发自定义事件,把校验结果传出去 this.fire('date-validation-change', { isValid: dateHasValue }); } });
父元素代码
<!-- 模板里监听子元素事件 --> <birthdate on-date-validation-change="_onDateValidation"></birthdate>
Polymer({ is: 'parent-element', behaviors: [Polymer.IronValidatableBehavior], _onDateValidation(e) { // 直接在父元素的事件处理器里调用setInvalidStates,上下文天然正确 this.setInvalidStates(!e.detail.isValid); }, setInvalidStates(isInvalid) { this.set('invalid', isInvalid); // 你的其他状态设置逻辑 } });
方案2:传递回调时绑定父元素上下文
如果一定要直接传递回调函数,需要用bind()强制绑定父元素的this,确保函数能正确指向父元素:
父元素调用子元素方法时
ready() { super.ready(); // 用bind(this)把setInvalidStates的上下文绑定到父元素 this.$.birthdate.checkIfDateHasValue(this.setInvalidStates.bind(this)); }
子元素接收并调用回调
checkIfDateHasValue(setInvalidStates) { const dateHasValue = /* 你的校验逻辑 */; // 现在setInvalidStates不再是undefined,且调用时上下文正确 if (setInvalidStates) { setInvalidStates(!dateHasValue); } }
方案3:用ES6箭头函数包装回调(环境支持时推荐)
如果你的项目允许使用ES6语法(Polymer 1.x配合babel或现代浏览器都支持),箭头函数会自动继承外层上下文,写法更简洁:
父元素调用代码
this.$.birthdate.checkIfDateHasValue((isInvalid) => this.setInvalidStates(isInvalid));
额外注意点
- 确认父元素中确实存在
setInvalidStates方法:IronValidatableBehavior本身并没有提供这个方法,需要你自己实现(比如用来更新invalid属性),如果方法不存在,传递时自然会是undefined。 - 避免直接通过模板属性绑定原始函数:比如
<birthdate check-fn="[[setInvalidStates]]">这种写法会丢失上下文,必须通过计算属性返回绑定后的函数:
// 父元素中定义计算属性 _boundSetInvalidStates: { type: Function, value() { return this.setInvalidStates.bind(this); } }
然后模板里用<birthdate check-fn="[[_boundSetInvalidStates]]">
内容的提问来源于stack exchange,提问作者dman
相关产品推荐
相关产品推荐

