ThingsBoard Widget:毫秒转分钟配置提交值类型异常修复
问题根因
HTML原生value属性无论是否添加引号,存储的默认类型都是字符串。Angular Material的mat-option在使用无方括号的原生value绑定时,会直接读取DOM上的字符串属性值,不会自动做类型转换,因此哪怕代码里写value=1800000,表单控件实际接收到的也是字符串"1800000",这是DOM原生特性,和Angular、ThingsBoard的业务逻辑无关。
方案1:修复现有下拉选择方案(改动最小,推荐)
将原生value属性替换为Angular的方括号属性绑定[value],此时绑定的内容会作为JavaScript数值字面量解析,不会自动转成字符串,仅需修改HTML模板即可:
<mat-form-field fxFlex class="mat-block"> <mat-label>Disconnection Timeout</mat-label> <mat-select matInput formControlName="inactivityTimeout"> <mat-option [value]="1800000">30 min</mat-option> <mat-option [value]="3600000">60 min</mat-option> <mat-option [value]="7200000">120 min</mat-option> </mat-select> </mat-form-field>
修改后原有控制器的数字正则校验逻辑可直接复用,表单控件拿到的值会是标准Number类型,提交到后端无需额外转码。
- 如果编辑旧数据时下拉框回显为空,是因为后端返回的历史超时值可能为字符串类型,在初始化
inactivityTimeout表单控件默认值时,用Number(原属性值)做一次类型转换即可正常匹配选项。
方案2:改为分钟单位输入框+提交时自动转毫秒
如果需要支持用户自定义超时时间、不局限于固定下拉选项,可按如下逻辑改造:
- 替换HTML模板中的下拉选择为数字输入框,明确标注单位:
<mat-form-field fxFlex class="mat-block"> <mat-label>断连不活动超时时间(分钟)</mat-label> <input matInput type="number" formControlName="inactivityTimeoutMin" min="1"> </mat-form-field>
- 修改控制器中的表单组配置,替换原有毫秒字段为分钟输入控件,在初始化、提交逻辑中做单位转换:
vm.editEntityFormGroup = vm.fb.group({ entityName: ['', [vm.validators.required]], entityType: [null], entityLabel: [null], type: ['', [vm.validators.required]], attributes: vm.fb.group({ // 替换原有的inactivityTimeout控件为分钟输入控件 inactivityTimeoutMin: [null, [vm.validators.required, vm.validators.min(1), vm.validators.pattern(/^[1-9][0-9]*$/)]], }), oldRelations: vm.fb.array([]), relations: vm.fb.array([]) }); // 表单初始化时,将后端返回的毫秒值转为分钟回填 const originTimeout = /* 接口返回的原有inactivityTimeout毫秒值 */; vm.editEntityFormGroup.get('attributes.inactivityTimeoutMin').patchValue( originTimeout ? Math.round(originTimeout / 60000) : null ); // 在原有save()提交逻辑中,将分钟值转为毫秒后再提交 const formValue = vm.editEntityFormGroup.value; const submitParams = { ...formValue, attributes: { ...formValue.attributes, inactivityTimeout: Number(formValue.attributes.inactivityTimeoutMin) * 60 * 1000 } }; // 提交前删除多余的inactivityTimeoutMin字段,用submitParams作为最终提交参数即可
- 不建议通过
valueChanges订阅实时做毫秒/分钟转换,容易触发表单值的循环更新,放在提交逻辑中做一次性转换稳定性最高,调试成本最低。 - 如果需要保留预设下拉+自定义输入的组合能力,可基于
mat-select的自定义模板扩展,转换逻辑和上述规则一致。
内容的提问来源于stack exchange,提问作者ellicon514
相关产品推荐
相关产品推荐

