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

Polymer JS触发on-change事件时预选中表单值不生效问题

问题根因

这个问题是Polymer响应式机制和dom-repeat渲染规则共同导致的,核心有3个问题:

  • 直接修改了原serviceTypeItems数组中的对象属性,没有做值重置逻辑,切换业务类型时旧值会残留,同时直接修改源数据会产生全局副作用
  • 没有使用Polymer提供的响应式API通知属性变化,内部状态更新后视图监听不到变更
  • dom-repeat默认按对象引用判断是否需要重新渲染,你返回的数组内是原有对象引用,就算属性改了也不会触发重渲染

修复方案

步骤1:给dom-repeat添加key属性

让dom-repeat按业务唯一标识serviceTypeId比对条目,而不是按对象引用,触发属性变更后的重渲染:

<template is="dom-repeat"
   items="{{_selectedServiceType(_contract.serviceTypeIds, serviceTypeItems, _contract.businessTypeId)}}"
   as="_serviceTypeDetails"
   key="serviceTypeId">
<!-- 原有内容保持不变 -->
</template>

步骤2:修改_selectedServiceType计算函数逻辑

修改点包括:不直接修改源数据对象、增加属性重置逻辑、调用Polymer响应式API通知变更:

_selectedServiceType(val1, val2, val3) {
  var returnItems = [];
  if (val1 != undefined) {
    // 统一处理选中的服务类型ID
    const selectedIds = val1 === '-1' 
      ? val2.map(item => String(item.serviceTypeId)) 
      : String(val1).split(',');

    for (let i = 0; i < val2.length; i++) {
      const currentSt = val2[i];
      if (selectedIds.includes(String(currentSt.serviceTypeId))) {
        // 浅拷贝原对象,不修改源数据
        const stCopy = Object.assign({}, currentSt);

        // 按业务类型赋值,同时处理不同类型的属性重置,避免旧值残留
        if (val3 === "2") { // 商业类
          stCopy.sitesStartDateAligned = true;
          stCopy.noOfSites = undefined;
          stCopy.pricingMethodId = undefined;
        } else if (val3 === "1") { // 住宅类
          stCopy.noOfSites = 1;
          stCopy.pricingMethodId = 2;
          stCopy.sitesStartDateAligned = false;
        }

        // 迭代ID规则优先级最高
        if (this._contract?.iterationId === '2' || this._contract?.iterationId === '3') {
          stCopy.pricingMethodId = 1;
        }

        returnItems.push(stCopy);
      }
    }
  }

  // 用Polymer的set方法赋值,触发响应式更新
  this.set('_contract.serviceTypeDetails', returnItems);
  // 通知数组下所有子属性变更,强制dom-repeat刷新
  this.notifyPath('_contract.serviceTypeDetails.*');
  return returnItems;
}

步骤3:补全_refreshFields事件逻辑(可选)

如果切换业务类型时计算函数没有自动触发,可以在绑定的change事件中手动触发重新计算:

_refreshFields() {
  this._selectedServiceType(
    this._contract.serviceTypeIds, 
    this.serviceTypeItems, 
    this._contract.businessTypeId
  );
}

内容的提问来源于stack exchange,提问作者Fighithebird

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:15:03