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

如何为代码生成元素绑定Knockout,或优化dxForm重绘时机?

问题

我在使用带数据绑定的DevExtreme dxForm组件时,给某个分组项添加了自定义模板,但formSettings.formData更新时,模板里的card内容不会同步更新——因为模板内元素未做数据绑定,手动添加data-bind属性也不生效。

我试过两种局部重绘表单的方法,均存在问题:

  1. 在表单不可见时执行重绘,jQuery找不到元素导致失败
  2. 在弹窗显示后执行,但需等待动画完成才触发,会显示约半秒的旧数据

相关代码

dxForm配置代码

formSettings: {
    formData: ko.observable(),
    scrollingEnabled: true,
    items: [{
        itemType: 'group',
        name: 'LabelInfo',
        caption: 'Infos vom Label',
        template(data, itemElement) {
            const card = document.createElement('div');
            card.classList.add('card');
            itemElement.append(card);

            const cardBody = document.createElement('div');
            cardBody.classList.add('card-body', 'lead');
            card.append(cardBody);

            for (let i = 1; i <= 4; i++) {
                cardBody.append(document.createTextNode(data.formData[`line${i}`]));
                if (i < 4) cardBody.append(document.createElement('br'));
            }
        }
    },
    // ... 其他表单项
    ]
}

尝试的重绘代码1

vm.lsl.formSettings.formData.subscribe(function () {
    // 刷新LabelInfo项
    $('#lsl-form').dxForm('instance').itemOption('LabelInfo', 'visible', true);
});

尝试的重绘代码2

vm.lsl.formSettings.formData(result.packagingInfo);
$('#lsl-popup').dxPopup('instance').show().then(() => $('#lsl-form').dxForm('instance').itemOption('LabelInfo', 'visible', true));

解决方案

方法一:给自定义模板添加Knockout数据绑定

利用Knockout的响应式绑定实现模板内容自动更新,无需手动重绘:

template(data, itemElement) {
    const card = document.createElement('div');
    card.classList.add('card');
    itemElement.append(card);

    const cardBody = document.createElement('div');
    cardBody.classList.add('card-body', 'lead');
    card.append(cardBody);

    // 通过ko.computed监听formData变化,自动生成HTML内容
    ko.applyBindingsToNode(cardBody, {
        html: ko.computed(() => {
            const formData = data.formData();
            let htmlContent = '';
            for (let i = 1; i <= 4; i++) {
                htmlContent += formData[`line${i}`] || '';
                if (i < 4) htmlContent += '<br>';
            }
            return htmlContent;
        })
    }, data);
}

说明:ko.computed会自动监听formData的变化,实时更新绑定的HTML内容,完全避免手动重绘的问题。

方法二:正确触发表单项重绘

若不想使用Knockout绑定,可调用dxForm专属API重绘指定项,并选对执行时机:

优化重绘逻辑

vm.lsl.formSettings.formData.subscribe(function () {
    const formInstance = $('#lsl-form').dxForm('instance');
    if (formInstance) {
        // 直接重绘指定项,比修改visible属性更高效
        formInstance.repaintItem('LabelInfo');
    }
});

配合弹窗的正确时机

监听弹窗的shown事件(弹窗完全显示、元素渲染完成后触发),避免动画等待导致的旧数据显示:

// 绑定弹窗shown事件
$('#lsl-popup').dxPopup('instance').on('shown', () => {
    const formInstance = $('#lsl-form').dxForm('instance');
    if (formInstance) {
        formInstance.repaintItem('LabelInfo');
    }
});

// 设置数据并显示弹窗
vm.lsl.formSettings.formData(result.packagingInfo);
$('#lsl-popup').dxPopup('instance').show();

说明:repaintItem是DevExtreme专为单个表单项提供的重绘API,比修改可见性更精准;shown事件确保表单元素已存在,不会出现找不到元素的问题。


内容的提问来源于stack exchange,提问作者André Reichelt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:45:44