knockout.js 以编程方式将挖空文本绑定应用于代码生成的元素

gudnpqoy  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(142)

在我的代码中,我使用了一个数据绑定的DevExtreme 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'));
            }
        }
    },
    // ...
    ]
}

问题是,很明显,这个卡片元素在formSettings.formData发生任何变化后都不会更新,因为它不是数据绑定的。将数据绑定属性添加到卡片主体的节点上也不会起作用,因为它们没有被执行。
有几种方法可以让dxForm部分重绘。但是,这是相当笨拙的,因为我的表单包含在一个弹出窗口中。我的第一次尝试失败了,因为在更新可观察项时表单是不可见的,因此jQuery返回一个空数组:

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

我的第二个想法是在显示弹出窗口后调用重绘。然而,这只有在所有动画都完成后才会触发,它会显示带有旧数据的卡片大约半秒钟(这看起来很愚蠢)。

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

是否有一种方法可以通过编程方式正确地数据绑定模板,或者找到一个更好的时机来重新绘制表单?

e3bfsja2

e3bfsja21#

有一个叫做applyBindingsToNode的函数,很遗憾它没有文档,但是它应该能够做你想要的事情:

for (let i = 1; i <= 4; i++) {
    ko.applyBindingsToNode(cardBody, { text: data.formData[`line${i}`] });
    if (i < 4) cardBody.append(document.createElement('br'));
}

相关问题