Importing JavaScript Resources in QML

JavaScript 资源可以被QML文档或其他JavaScript资源导入. JavaScript 资源可以通过相对或绝对URL导入. 在相对URL的情况下, 这个位置是相对于包含导入的QML 文档JavaScript 资源的位置. 如果脚本文件不可访问, 则会发生错误. 如果需要从网络资源获取JavaScript, 则组件的status将设置为"正在加载", 直到脚本下载完毕.

JavaScript资源还可以导入QML模块和其他JavaScript资源. JavaScript资源中导入语句的语法与QML文档中的导入语句略有不同, QML文档将在下面详细介绍.

向QML文档导入JavaScript资源

向QML文档导入JavaScript资源的语法如下:


  import "ResourceURL" as Qualifier

例如:


  import "jsfile.js" as Logic

导入的JavaScript资源总是使用关键字 "as" 限定. JavaScript资源的限定符必须以大写字母开头, 并且必须是唯一的, 因此限定符和JavaScript文件之间始终存在一对一的映射. (这也意味着限定符的命名不能与DateMath等内置JavaScript对象相同).

导入的JavaScript文件中定义的函数可通过"Qualifier.functionName(params)"语法用于导入QML文档中定义的对象. JavaScript资源中的函数可以采用参数, 其类型可以是任何QML值类型或对象类型, 也可以是正常的JavaScript类型. 当从QML调用此类函数时, 正常的数据类型转换规则将应用于参数和返回值.

在JavaScript资源中导入

QtQuick 2.0开始, QML支持JavaScript资源使用标准QML导入语法的变体导入其他JavaScript资源及QML类型的命名空间(适用于前面描述的所有规则和限定).

为了让JavaScript资源能够在QtQuick 2.0中以这种方式导入另一个脚本或QML模块, QML定义了一些额外的语义:

  • 带有导入的脚本将不会从导入它的QML文档继承导入(例如, 因此访问Component.errorString将失败)
  • 没有导入的脚本将从导入它的QML文档继承导入(例如, 因此访问Component.errorString将成功)
  • 共享脚本(., 定义为.pragma库)不会从任何QML文档继承导入, 即使它不导入其他脚本或模块

第一个语义在概念上是正确的, 因为任何数量的QML文件都可能导入特定的脚本. 为了向后兼容性, 保留第二个语义. 第三个语义与共享脚本的当前语义保持不变, 但在这里针对新的可能情况(脚本导入其他脚本或模块)进行澄清.

从另一个JavaScript资源导入JavaScript资源

JavaScript资源可以通过以下方式导入另一个JavaScript资源:


  .import "filename.js" as Qualifier

例如:


  .import "factorial.js" as MathFunctions

从JavaScript资源导入QML模块

JavaScript资源可以通过以下方式导入QML模块:


  .import TypeNamespace MajorVersion.MinorVersion as Qualifier

For example:


  .import Qt.test 1.0 as JsQtTest

In particular, this may be useful in order to access functionality provided via a singleton type; see qmlRegisterSingletonType() for more information.

Note: The .import syntax doesn't work for scripts used in the WorkerScript

Including a JavaScript Resource from Another JavaScript Resource

When a JavaScript file is imported, it must be imported with a qualifier. The functions in that file are then accessible from the importing script via the qualifier (that is, as Qualifier.functionName(params)). Sometimes it is desirable to have the functions made available in the importing context without needing to qualify them, and in this circumstance the Qt.include() function may be used to include one JavaScript file from another. This copies all functions from the other file into the current file's namespace, but ignores all pragmas and imports defined in that file.

例如, 左下方的QML代码调用script.js中的showCalculations(), 而script.mjs又调用factorial.mjs中的factorial(), 因为它使用import包含了factorial.mjs. 在不使用ECMAScript模块和不限定导入的情况下, 调用Qt.include()函数从一个JavaScript包含另一个.


  import QtQuick 2.0
  import "script.js" as MyScript

  Item {
      width: 100; height: 100

      MouseArea {
          anchors.fill: parent
          onClicked: {
              MyScript.showCalculations(10)
              console.log("Call factorial() from QML:",
                  MyScript.factorial(10))
          }
      }
  }


  // script.js
  Qt.include("factorial.js")

  function showCalculations(value) {
      console.log(
          "Call factorial() from script.js:",
          factorial(value));
  }


  // factorial.js
  function factorial(a) {
      a = parseInt(a);
      if (a <= 0)
          return 1;
      else
          return a * factorial(a - 1);
  }

Notice that calling Qt.include() copies all functions from factorial.js into the MyScript namespace, which means the QML component can also access factorial() directly as MyScript.factorial().