1/**************************************************************************** 2** 3** Copyright (C) 2017 The Qt Company Ltd. 4** Contact: https://www.qt.io/licensing/ 5** 6** This file is part of the documentation of the Qt Toolkit. 7** 8** $QT_BEGIN_LICENSE:FDL$ 9** Commercial License Usage 10** Licensees holding valid commercial Qt licenses may use this file in 11** accordance with the commercial license agreement provided with the 12** Software or, alternatively, in accordance with the terms contained in 13** a written agreement between you and The Qt Company. For licensing terms 14** and conditions see https://www.qt.io/terms-conditions. For further 15** information use the contact form at https://www.qt.io/contact-us. 16** 17** GNU Free Documentation License Usage 18** Alternatively, this file may be used under the terms of the GNU Free 19** Documentation License version 1.3 as published by the Free Software 20** Foundation and appearing in the file included in the packaging of 21** this file. Please review the following information to ensure 22** the GNU Free Documentation License version 1.3 requirements 23** will be met: https://www.gnu.org/licenses/fdl-1.3.html. 24** $QT_END_LICENSE$ 25** 26****************************************************************************/ 27/*! 28\page qtqml-javascript-resources.html 29\title Defining JavaScript Resources in QML 30\brief Description of how JavaScript files may be defined for use in QML 31 32The program logic for a QML application may be defined in JavaScript. The 33JavaScript code may either be defined in-line in QML documents, or separated 34into JavaScript files (known as \c {JavaScript Resources} in QML). 35 36There are two different kinds of JavaScript resources which are supported in 37QML: code-behind implementation files, and shared (library) files. Both kinds 38of JavaScript resource may be \l{qtqml-javascript-imports.html}{imported} by 39other JavaScript resources, or included in \l{qtqml-modules-topic.html} 40{QML modules}. 41 42\section1 Code-Behind Implementation Resource 43 44Most JavaScript files imported into a QML document are stateful implementations 45for the QML document importing them. In these cases, each instance of the QML 46object type defined in the document requires a separate copy of the JavaScript 47objects and state in order to behave correctly. 48 49The default behavior when importing JavaScript files is to provide a unique, 50isolated copy for each QML component instance. If that JavaScript file does 51not import any resources or modules with a \c{.import} statement, its code will 52run in the same scope as the QML component instance and consequently can access 53and manipulate the objects and properties declared in that QML component. 54Otherwise, it will have its own unique scope, and objects and properties of the 55QML component should be passed to the functions of the JavaScript file as 56parameters if they are required. 57 58An example of a code-behind implementation resource follows: 59 60\code 61// MyButton.qml 62import QtQuick 2.0 63import "my_button_impl.js" as Logic // A new instance of this JavaScript resource 64 // is loaded for each instance of Button.qml. 65 66Rectangle { 67 id: rect 68 width: 200 69 height: 100 70 color: "red" 71 72 MouseArea { 73 id: mousearea 74 anchors.fill: parent 75 onClicked: Logic.onClicked(rect) 76 } 77} 78\endcode 79 80\code 81// my_button_impl.js 82var clickCount = 0; // this state is separate for each instance of MyButton 83function onClicked(button) { 84 clickCount += 1; 85 if ((clickCount % 5) == 0) { 86 button.color = Qt.rgba(1,0,0,1); 87 } else { 88 button.color = Qt.rgba(0,1,0,1); 89 } 90} 91\endcode 92 93In general, simple logic should be defined in-line in the QML file, but more 94complex logic should be separated into code-behind implementation resources 95for maintainability and readability. 96 97\section1 Shared JavaScript Resources (Libraries) 98 99By default, JavaScript files imported from QML share their context with the QML 100component. That means the JavaScript files have access to the same QML objects 101and can modify them. As a consequence, each import must have a unique copy of 102these files. 103 104\l {Defining JavaScript Resources in QML#Code-Behind Implementation Resource} 105{The previous section} covers stateful imports of JavaScript files. However, 106some JavaScript files are stateless and act more like reusable libraries, in 107the sense that they provide a set of helper functions that do not require 108anything from where they were imported from. You can save significant amounts 109of memory and speed up the instantiation of QML components if you mark such 110libraries with a special pragma, as shown in the following example. 111 112\code 113// factorial.js 114.pragma library 115 116var factorialCount = 0; 117 118function factorial(a) { 119 a = parseInt(a); 120 121 // factorial recursion 122 if (a > 0) 123 return a * factorial(a - 1); 124 125 // shared state 126 factorialCount += 1; 127 128 // recursion base-case. 129 return 1; 130} 131 132function factorialCallCount() { 133 return factorialCount; 134} 135\endcode 136 137The pragma declaration must appear before any JavaScript code excluding comments. 138 139Note that multiple QML documents can import \c{"factorial.js"} and call the 140factorial and factorialCallCount functions that it provides. The state of the 141JavaScript import is shared across the QML documents which import it, and thus 142the return value of the factorialCallCount function may be non-zero when called 143within a QML document which never calls the factorial function. 144 145For example: 146 147\code 148// Calculator.qml 149import QtQuick 2.0 150import "factorial.js" as FactorialCalculator // This JavaScript resource is only 151 // ever loaded once by the engine, 152 // even if multiple instances of 153 // Calculator.qml are created. 154 155Text { 156 width: 500 157 height: 100 158 property int input: 17 159 text: "The factorial of " + input + " is: " + FactorialCalculator.factorial(input) 160} 161\endcode 162 163As they are shared, .pragma library files cannot access QML component instance 164objects or properties directly, although QML values can be passed as function 165parameters. 166 167*/ 168