[OutSystems] 用 JavaScript 改变输入值的方法:
使用JavaScript通过DOM元素的.value进行Input Widget值的更改时,不会将值反映到与Input相关联的变量中。
我想寻找解决方案,因为在为输入添加功能的模块时遇到了困难。
环境信息
个人环境(版本11.21.0(构建39357))
服务工作室(版本11.54.13)
样本
HousesoftSampleReactive 的版本是 1.0.19。
请参考 ChangeInputValueWithJS 屏幕说明。
答案:例子:使用JavaScript修改input.value的值。
首先验证一下错误情况的实现。
以下的代码在JavaScript元素中写入后无法正常工作。
提醒一下,Input Widget的Id被传递给JavaScript元素作为输入参数。
document.getElementById($parameters.InputId).value = "JavaScriptでinput.valueを更新"

考虑原因:可能是由于React的原因
OutSystems的Reactive/Mobile使用React作为前端框架。
因此,当在客户端发生奇怪的情况时,应该怀疑React。
所以,当我用关键词“React”搜索时,找到了以下页面。
使用原始 JavaScript 改变 React 输入值
React覆盖了原生的JavaScript onChange行为。在React的眼中,触发onChange事件对输入框的值没有任何改变。
由于React改变了JavaScript自带的onChange行为,所以仅仅触发onChange事件在React的视角下看起来并没有改变值。
使用valuetracker进行对策。
在引用的页面中提到的对策是在「考虑原因」一节中提及的。
由于 Platform Server v11.12.0,React 的版本是 16。因此,可以采用引用页面中提到的使用 _valueTracker 的方法来解决。
JavaScript中的代码如下所示。
// see: https://chuckconway.com/changing-a-react-input-value-from-vanilla-javascript/
// 1
let element = document.getElementById($parameters.InputId);
// 2
let lastValue = element.value;
element.value = "JavaScriptでinput.valueを更新してdispatchEvent(_valueTracker利用)";
let ev = new Event ("input", { bubbles: true });
// 3
let tracker = element._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
}
// 4
element.dispatchEvent(ev);
-
- 获取与Input Widget相对应的input元素
-
- 保存先前的值,并通过.value属性修改值
-
- 将_valueTracker的值设置为先前的值
- 触发input事件
在其中的流程中,第3步骤非常关键。
不过,由于前缀带有”_”,所以似乎并不太适合公然使用。

使用第二种方法,直接调用输入的setter函数。
如果React要修改原始的setter函数,那么可以使用修改前的setter函数来设置值,这是一个想法。
这是在“React中触发更改或输入事件的最佳方法”的最佳答案中提到的方法。
// see: https://stackoverflow.com/questions/23892547/what-is-the-best-way-to-trigger-change-or-input-event-in-react-js#46012210
// 1
let element = document.getElementById($parameters.InputId);
// 2
let nativeSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
nativeSetter.call(element, "JavaScriptでinputのsetterを呼んでdispatchEvent");
// 3
let ev = new Event ("input", { bubbles: true });
element.dispatchEvent(ev);
-
- 获取与Input Widget相对应的input元素
-
- 使用input元素的setter函数(通过PropertyDescriptor的set函数获取)来更新值
- 触发input事件
同样采用这种方法的还有名为Input Masks Library的Forge组件。
在应用中
我想选择只使用纯粹的JavaScript实现第二种方法。
然而,我也希望考虑到OutSystems的升级(包括React的升级和前端框架本身的更改)可能导致它无法使用的情况。
所以,我们可以将这种行为的特性分离成公共组件的Block或Client Action,并且使其能够在需要时轻松替换。