HTML 辅助函数

直接从 HTML/JavaScript 访问 Ninox 函数

Ninext 允许从 HTML 或 JavaScript 代码直接调用 Ninox 函数,从而让创建与 Ninox 集成的 HTML 界面变得更容易。虽然 Ninox 的 html 函数可以在公式中方便地生成 HTML 组件,但若不借助更复杂的方案,与 Ninox 逻辑交互仍然很困难。

以一个需要触发 Ninox 相关行为的输入框为例。传统做法是使用 REST API 把数据发送到服务器,再由服务器更新本地显示。这种方法虽然有效,却有若干缺点:

  • 技术复杂度:实现 API 调用需要对 JavaScript 中的 HTTP 请求有扎实的理解。
  • 交互性受限:更改只影响服务器端的数据,无法触发界面上的即时本地更新。

有了 Ninext,集成变得更顺畅:您可以将 HTML/JavaScript 组件直接与 Ninox 函数关联。这提升了应用的交互性,而无需承受 API 调用通常带来的种种约束。

callNinoxFunction

callNinoxFunction 函数让您可以从 JavaScript 代码调用 Ninox 脚本:HTML 事件属性、原生 JS 代码块……这种集成为与 Ninox 交互提供了极大的灵活性,特别适用于:

  • 发送输入框的值,
  • 在 onclick、onfocus 或 onblur 等事件中,或在定时器(setTimeout)到期时执行动作,
  • 借助回调处理异步操作。

格式与参数

Ninox
ninext.callNinoxFunction(functionName, htmlElement, ...args, [callback])
参数说明
functionName要调用的 Ninox 函数的名称。
htmlElement在哪里查找该函数。可以是 HTML 元素本身(例如 this 或 document.getElementById("myId"))或其 ID(例如 "myId"):函数会在显示该元素的公式中查找。也可以是对某条记录的引用(参见“通过引用指定函数”)。或者是 null,表示全局代码中的函数(参见“调用全局代码中的函数”)。
...args传递给 Ninox 函数的附加参数(参见“参数”)。
callback(可选)用于异步处理结果的函数。如果提供,它将以 (error, result) 被调用。

返回值

同步模式(不带回调)

该函数立即返回一个 JSON 对象,其结构为下列之一:

成功时:

Ninox
{
    result: <value>    // The value returned by the Ninox function
}

出错时:

Ninox
{
    error: <string>    // Error message describing what went wrong
}

只有当 Ninox 函数无需等待就执行完毕时,结果才会出现在其中。如果它需要等待(例如某条记录尚待加载,或有异步处理),该对象会在它完成之前返回,其中没有结果。如有疑问,请传入一个回调函数。

异步模式(带回调)

当最后一个参数提供了回调函数时,该回调会收到两个参数:

Ninox
callback(error, result)
参数说明
error成功时为空(null 或 undefined);否则是一段描述错误的文本。它不是 Error 对象:请直接显示 error 本身,而不是 error.message。
resultNinox 函数返回的值;若发生错误则为空。

当调用无法完成时,error 会被填写:找不到函数、元素或记录,或代码无法编译。

调用全局代码中的函数

第二个参数为 null 时,Ninext 会调用数据库全局代码中的函数。该函数在没有上下文记录的情况下执行。全局代码中有这样一个函数:

Ninox
function greet(name : text) do
    alert("Hello " + name)
end;

JavaScript 这样调用它:

Ninox
ninext.callNinoxFunction('greet', null, 'Sofia');

这也是从原生 JS 代码块中调用全局代码函数的方法,因为代码块无法直接看到这些函数。

通过引用指定函数

第二个参数也可以是一段指定某条记录的文本。Ninext 会先查找带有该 ID 的 HTML 元素,然后读取这个引用:函数随后在这条记录(this)的上下文中执行。

引用在……中查找函数
'A13'该记录所在表的触发器中:第一个包含该函数的触发器。
'A13.afterUpdate'表的这个触发器中。
'A13.Summary'该表“Summary”字段的公式中。

A13 是记录的完整 ID:表的 ID 后接记录的编号。表触发器使用其内部名称:afterCreate、afterUpdate 或 onClick。字段可以用其 ID 或名称指定,名称不加引号。如果名称中含有括号或其他标点符号,调用会失败(JavaScript 异常):此时请用字段的 ID 来指定它。

参数

参数从 JavaScript 传到 Ninox 的方式如下:

在 JavaScript 中在 Ninox 中
文本文本,引号也一并传递
数字数字
布尔值布尔值(true 或 false)
对象或数组JSON:将参数声明为 any
日期(Date)毫秒数:将参数声明为 number

对象的值可以包含引号、换行和重音字符(自 3.2.0 版起)。不要把 null 或 undefined 作为参数传入:否则调用会引发 JavaScript 异常。

工作原理

核心思路是在 HTML 页面的上下文中执行 Ninox 脚本。其运作方式如下:

  1. 定义 Ninox 函数
    在您的 Ninox 公式中定义一个函数(例如 myOnblur),用于处理从 JavaScript 传来的参数。Ninext 只从公式中提取这个函数:它看不到公式中其他地方声明的变量或其他函数。它在当前记录的上下文中执行(相当于 Ninox 中的 this)。
  2. 创建 HTML 界面
    在公式中嵌入一个 HTML 组件(例如一个输入框)。在事件属性(例如 onblur)中,使用 callNinoxFunction 调用相应的 Ninox 函数,并传入所需的参数。
  3. 触发事件
    当 HTML 事件被触发时,callNinoxFunction 会调用指定的 Ninox 函数,将其隔离,并以给定的上下文和参数(例如输入框的值)执行它。

这一机制在模拟原生触发器行为的同时,还允许向 Ninox 函数的执行传入一个或多个自定义参数。

用法示例

基础示例:带 onblur 的输入框

  1. 定义 Ninox 函数

在您的 Ninox 公式中添加以下函数:

Ninox
function myOnblur(inputValue : text) do
    alert("Input of record " + this.Id + " is " + inputValue)
end;

该函数会弹出一个提示,显示当前记录的 ID 和传入的值。

  1. 集成 HTML 输入框

接着,插入以下 HTML 代码以显示一个输入框,并定义 onblur 事件:

Ninox
function myOnblur(inputValue : text) do
    alert("Input of record " + this.Id + " is " + inputValue)
end;

html("
    <input
        class='nx-input nx-input--editing'
        style='width: 100%; height: 100%;'
        onblur=""ninext.callNinoxFunction('myOnblur', this, this.value)""
    />
")

工作原理:

  • 当用户离开输入框时(onblur 事件),
  • 调用 ninext.callNinoxFunction 函数,并传入:
    • 'myOnblur':要执行的 Ninox 函数的名称,
    • this:HTML 元素本身,
    • this.value:输入框的当前值。

这样可以确保 Ninox 脚本 myOnblur 在当前记录的上下文中运行,就像由 Ninox 原生触发一样,同时还能把输入框的值作为参数接收。

同步用法示例

Ninox
// Basic call - checking the result
const response = ninext.callNinoxFunction('myFunction', this, 'param1');
if (response.error) {
    console.error('Error:', response.error);
} else {
    console.log('Result:', response.result);
}

// Direct access to result (when you're confident there's no error)
alert(ninext.callNinoxFunction('getValue', this).result);

// With error handling
const res = ninext.callNinoxFunction('calculateTotal', 'myButtonId', 100, 0.2);
if (res.error) {
    alert('Calculation failed: ' + res.error);
} else {
    document.getElementById('total').textContent = res.result;
}

异步用法示例(带回调)

Ninox
// Basic callback usage
ninext.callNinoxFunction('myFunction', this, 'param1', function(error, result) {
    if (error) {
        console.error('Error:', error);
    } else {
        console.log('Result:', result);
    }
});

// Update UI after async operation
ninext.callNinoxFunction('loadData', 'myContainer', recordId, function(error, result) {
    if (error) {
        alert('Failed to load data: ' + error);
        return;
    }
    document.getElementById('output').innerHTML = result;
});

// Using arrow function syntax
ninext.callNinoxFunction('calculateTotal', this, 100, 0.2, (error, result) => {
    if (!error) {
        document.getElementById('total').textContent = result;
    }
});

何时使用回调?

在以下情况下请使用回调模式:

  • Ninox 函数执行异步操作(API 调用、复杂计算),
  • 您需要在函数完成后更新界面,
  • 您希望按顺序串联多个操作。

要点

  • 上下文化:
    Ninox 函数执行时,this 代表当前记录,或由引用指定的记录,从而保证执行上下文的一致性。全局代码中的函数在没有记录的情况下执行。
  • 灵活性:
    您可以通过 ...args 添加任意数量的参数,使 Ninox 函数的行为能够适应您应用的具体需求。
  • 错误处理:
    error 表示调用无法完成:找不到函数、元素或记录,或代码无法编译。它是一段文本,应原样显示。对于可能需要等待的函数,请传入一个回调函数。
  • 用途广泛:
    该机制尤其适合在 HTML/JavaScript 用户界面与 Ninox 中定义的业务逻辑之间实现复杂的交互集成。