aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc/src/javascript/imports.qdoc
blob: 08acccbe21a52134d4259bda06d5abac138f2707 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page qtqml-javascript-imports.html
\title Importing JavaScript Files in QML Documents
\brief Description of how to import and use JavaScript files in QML documents

Both relative and absolute JavaScript URLs can be imported in QML documents.
In the case of a relative URL, the location is resolved relative to the
location of the \l {QML Document} that contains the import.  If the script
file is not accessible, an error will occur.  If the JavaScript needs to be
fetched from a network resource, the component's
\l {QQmlComponent::status()}{status} is set to "Loading" until the script has
been downloaded.

Imported JavaScript files are always qualified using the "as" keyword.  The
qualifier for JavaScript files must be unique, so there is always a one-to-one
mapping between qualifiers and JavaScript files. (This also means qualifiers
cannot be named the same as built-in JavaScript objects such as \c Date and
\c Math).

The functions defined in an imported JavaScript file are available to objects
defined in the importing QML document, via the \c{"Qualifier.functionName()"}
syntax.

\section1 Importing a JavaScript File from Another

In QtQuick 2.0, support has been added to allow JavaScript files to import
other JavaScript files and also QML type namespaces using a variation of the
standard QML import syntax (where all of the previously described rules and
qualifications apply).

A JavaScript file may import another in the following fashion:
\code
.import "filename.js" as Qualifier
\endcode
For example:
\code
.import "factorial.js" as MathFunctions
\endcode

A JavaScript file may import a QML type namespace in the following fashion:
\code
.import TypeNamespace MajorVersion.MinorVersion as Qualifier
\endcode

For example:
\code
.import Qt.test 1.0 as JsQtTest
\endcode

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

Due to the ability of a JavaScript file to import another script or QML module
in this fashion in QtQuick 2.0, some extra semantics are defined:
\list
\li a script with imports will not inherit imports from the QML file which imported it (so accessing Component.error will fail, for example)
\li a script without imports will inherit imports from the QML file which imported it (so accessing Component.error will succeed, for example)
\li a shared script (i.e., defined as .pragma library) does not inherit imports from any QML file even if it imports no other scripts
\endlist

The first semantic is conceptually correct, given that a particular script
might be imported by any number of QML files.  The second semantic is retained
for the purposes of backwards-compatibility.  The third semantic remains
unchanged from the current semantics for shared scripts, but is clarified here
in respect to the newly possible case (where the script imports other scripts
or modules).


\section2 Code-Behind Implementation Files

Most JavaScript files imported into a QML file are stateful implementations
for the QML file importing them.  In these cases, for QML component instances
to behave correctly each instance requires a separate copy of the JavaScript
objects and state.

The default behavior when importing JavaScript files is to provide a unique,
isolated copy for each QML component instance.  If that JavaScript file does
not import any other JavaScript files or QML type namespaces, its code will run
in the same scope as the QML component instance and consequently can can access
and manipulate the objects and properties declared in that QML component.
Otherwise, it will have its own unique scope, and objects and properties of the
QML component should be passed to the functions of the JavaScript file as
parameters if they are required.

\section2 Shared JavaScript Files (Libraries)

Some JavaScript files act more like libraries - they provide a set of helper
functions that take input and compute output, but never manipulate QML
component instances directly.

As it would be wasteful for each QML component instance to have a unique copy of
these libraries, the JavaScript programmer can indicate a particular file is a
shared library through the use of a pragma, as shown in the following example.

\code
// factorial.js
.pragma library

var factorialCount = 0;

function factorial(a) {
    a = parseInt(a);

    // factorial recursion
    if (a > 0)
        return a * factorial(a - 1);

    // shared state
    factorialCount += 1;

    // recursion base-case.
    return 1;
}

function factorialCallCount() {
    return factorialCount;
}
\endcode

The pragma declaration must appear before any JavaScript code excluding comments.

Note that multiple QML documents can import \c{"factorial.js"} and call the
factorial and factorialCallCount functions that it provides.  The state of the
JavaScript import is shared across the QML documents which import it, and thus
the return value of the factorialCallCount function may be non-zero when called
within a QML document which never calls the factorial function.

As they are shared, .pragma library files cannot access QML component instance
objects or properties directly, although QML values can be passed as function
parameters.

\section1 Including a JavaScript File from Another

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 \tt{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 \l{QML:Qt::include()}
{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.

For example, the QML code below left calls \c showCalculations() in \c script.js,
which in turn can call \c factorial() in \c factorial.js, as it has included
\c factorial.js using \l {QML:Qt::include()}{Qt.include()}.

\table
\row
\li {1,2} \snippet qml/integrating-javascript/includejs/app.qml 0
\li \snippet qml/integrating-javascript/includejs/script.js 0
\row
\li \snippet qml/integrating-javascript/includejs/factorial.js 0
\endtable

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


*/