7bbeddf9bc905bad5dba0a98e84085942c79e201
[profile/ivi/qtdeclarative.git] / src / qml / doc / src / documents / scope.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** GNU Free Documentation License
10 ** Alternatively, this file may be used under the terms of the GNU Free
11 ** Documentation License version 1.3 as published by the Free Software
12 ** Foundation and appearing in the file included in the packaging of
13 ** this file.
14 **
15 ** Other Usage
16 ** Alternatively, this file may be used in accordance with the terms
17 ** and conditions contained in a signed written agreement between you
18 ** and Nokia.
19 **
20 **
21 **
22 **
23 **
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27 /*!
28 \page qtqml-documents-scope.html
29 \title Scope and Naming Resolution
30 \brief overview of scope and naming resolution
31
32 QML property bindings, inline functions, and imported JavaScript files all
33 run in a JavaScript scope.  Scope controls which variables an expression can
34 access, and which variable takes precedence when two or more names conflict.
35
36 As JavaScript's built-in scope mechanism is very simple, QML enhances it to fit
37 more naturally with the QML language extensions.
38
39 \section1 JavaScript Scope
40
41 QML's scope extensions do not interfere with JavaScript's natural scoping.
42 JavaScript programmers can reuse their existing knowledge when programming
43 functions, property bindings or imported JavaScript files in QML.
44
45 In the following example, the \c {addConstant()} method will add 13 to the
46 parameter passed just as the programmer would expect irrespective of the
47 value of the QML object's \c a and \c b properties.
48
49 \code
50 QtObject {
51     property int a: 3
52     property int b: 9
53
54     function addConstant(b) {
55         var a = 13;
56         return b + a;
57     }
58 }
59 \endcode
60
61 That QML respects JavaScript's normal scoping rules even applies in bindings.
62 This totally evil, abomination of a binding will assign 12 to the QML object's
63 \c a property.
64
65 \code
66 QtObject {
67     property int a
68
69     a: { var a = 12; a; }
70 }
71 \endcode
72
73 Every JavaScript expression, function or file in QML has its own unique
74 variable object.  Local variables declared in one will never conflict
75 with local variables declared in another.
76
77 \section1 Element Names and Imported JavaScript Files
78
79 \l {QML Document}s include import statements that define the element names
80 and JavaScript files visible to the document.  In addition to their use in the
81 QML declaration itself, element names are used by JavaScript code when accessing
82 \l {Attached Properties} and enumeration values.
83
84 The effect of an import applies to every property binding, and JavaScript
85 function in the QML document, even those in nested inline components.  The
86 following example shows a simple QML file that accesses some enumeration
87 values and calls an imported JavaScript function.
88
89 \code
90 import QtQuick 2.0
91 import "code.js" as Code
92
93 ListView {
94     snapMode: ListView.SnapToItem
95
96     delegate: Component {
97         Text {
98             elide: Text.ElideMiddle
99             text: "A really, really long string that will require eliding."
100             color: Code.defaultColor()
101         }
102     }
103 }
104 \endcode
105
106 \section1 Binding Scope Object
107
108 Property bindings are the most common use of JavaScript in QML.  Property
109 bindings associate the result of a JavaScript expression with a property of an
110 object.  The object to which the bound property belongs is known as the binding's
111 scope object.  In this QML simple declaration the \l Item object is the
112 binding's scope object.
113
114 \code
115 Item {
116     anchors.left: parent.left
117 }
118 \endcode
119
120 Bindings have access to the scope object's properties without qualification.
121 In the previous example, the binding accesses the \l Item's \c parent property
122 directly, without needing any form of object prefix.  QML introduces a more
123 structured, object-oriented approach to JavaScript, and consequently does not
124 require the use of the JavaScript \c this property.
125
126 Care must be used when accessing \l {Attached Properties} from bindings due
127 to their interaction with the scope object.  Conceptually attached properties
128 exist on \e all objects, even if they only have an effect on a subset of those.
129 Consequently unqualified attached property reads will always resolve to an
130 attached property on the scope object, which is not always what the programmer
131 intended.
132
133 For example, the \l PathView element attaches interpolated value properties to
134 its delegates depending on their position in the path.  As PathView only
135 meaningfully attaches these properties to the root element in the delegate, any
136 sub-element that accesses them must explicitly qualify the root object, as shown
137 below.
138
139 \code
140 PathView {
141     delegate: Component {
142         Rectangle {
143             id: root
144             Image {
145                 scale: root.PathView.scale
146             }
147         }
148     }
149 }
150 \endcode
151
152 If the \l Image element omitted the \c root prefix, it would inadvertently access
153 the unset \c {PathView.scale} attached property on itself.
154
155 \section1 Component Scope
156
157 Each QML component in a QML document defines a logical scope.  Each document
158 has at least one root component, but can also have other inline sub-components.
159 The component scope is the union of the object ids within the component and the
160 component's root element's properties.
161
162 \code
163 Item {
164     property string title
165
166     Text {
167         id: titleElement
168         text: "<b>" + title + "</b>"
169         font.pixelSize: 22
170         anchors.top: parent.top
171     }
172
173     Text {
174         text: titleElement.text
175         font.pixelSize: 18
176         anchors.bottom: parent.bottom
177     }
178 }
179 \endcode
180
181 The example above shows a simple QML component that displays a rich text title
182 string at the top, and a smaller copy of the same text at the bottom.  The first
183 \c Text element directly accesses the component's \c title property when
184 forming the text to display.  That the root element's properties are directly
185 accessible makes it trivial to distribute data throughout the component.
186
187 The second \c Text element uses an id to access the first's text directly.  IDs
188 are specified explicitly by the QML programmer so they always take precedence
189 over other property names (except for those in the \l {JavaScript Scope}).  For
190 example, in the unlikely event that the binding's \l {Binding Scope Object}{scope
191 object}  had a \c titleElement property in the previous example, the \c titleElement
192 id would still take precedence.
193
194 \section1 Component Instance Hierarchy
195
196 In QML, component instances connect their component scopes together to form a
197 scope hierarchy.  Component instances can directly access the component scopes of
198 their ancestors.
199
200 The easiest way to demonstrate this is with inline sub-components whose component
201 scopes are implicitly scoped as children of the outer component.
202
203 \code
204 Item {
205     property color defaultColor: "blue"
206
207     ListView {
208         delegate: Component {
209             Rectangle {
210                 color: defaultColor
211             }
212         }
213     }
214 }
215 \endcode
216
217 The component instance hierarchy allows instances of the delegate component
218 to access the \c defaultColor property of the \c Item element.  Of course,
219 had the delegate component had a property called \c defaultColor that would
220 have taken precedence.
221
222 The component instance scope hierarchy extends to out-of-line components, too.
223 In the following example, the \c TitlePage.qml component creates two
224 \c TitleText instances.  Even though the \c TitleText element is in a separate
225 file, it still has access to the \c title property when it is used from within
226 the \c TitlePage.  QML is a dynamically scoped language - depending on where it
227 is used, the \c title property may resolve differently.
228
229 \code
230 // TitlePage.qml
231 import QtQuick 2.0
232 Item {
233     property string title
234
235     TitleText {
236         size: 22
237         anchors.top: parent.top
238     }
239
240     TitleText {
241         size: 18
242         anchors.bottom: parent.bottom
243     }
244 }
245
246 // TitleText.qml
247 import QtQuick 2.0
248 Text {
249     property int size
250     text: "<b>" + title + "</b>"
251     font.pixelSize: size
252 }
253 \endcode
254
255 Dynamic scoping is very powerful, but it must be used cautiously to prevent
256 the behavior of QML code from becoming difficult to predict.  In general it
257 should only be used in cases where the two components are already tightly
258 coupled in another way.  When building reusable components, it is preferable
259 to use property interfaces, like this:
260
261 \code
262 // TitlePage.qml
263 import QtQuick 2.0
264 Item {
265     id: root
266     property string title
267
268     TitleText {
269         title: root.title
270         size: 22
271         anchors.top: parent.top
272     }
273
274     TitleText {
275         title: root.title
276         size: 18
277         anchors.bottom: parent.bottom
278     }
279 }
280
281 // TitleText.qml
282 import QtQuick 2.0
283 Text {
284     property string title
285     property int size
286
287     text: "<b>" + title + "</b>"
288     font.pixelSize: size
289 }
290 \endcode
291
292 \section1 Overridden Properties
293
294 QML permits property names defined in an object declaration to be overridden by properties
295 declared within another object declaration that extends the first.  For example:
296
297 \code
298 // Displayable.qml
299 import QtQuick 2.0
300 Item {
301     property string title
302     property string detail
303
304     Text {
305         text: "<b>" + title + "</b><br>" + detail
306     }
307
308     function getTitle() { return title }
309     function setTitle(newTitle) { title = newTitle }
310 }
311
312 // Person.qml
313 import QtQuick 2.0
314 Displayable {
315     property string title
316     property string firstName
317     property string lastName
318
319     function fullName()  { return title + " " + firstName + " " + lastName }
320 }
321 \endcode
322
323 Here, the name \c title is given to both the heading of the output text for Displayable,
324 and also to the honorific title of the Person object.
325
326 An overridden property is resolved according to the scope in which it is referenced.
327 Inside the scope of the Person component, or from an external scope that refers
328 to an instance of the Person component, \c title resolves to the property
329 declared inside Person.qml.  The \c fullName function will refer to the \c title
330 property declared inside Person.
331
332 Inside the Displayable component, however, \c title refers to the property
333 declared in Displayable.qml.  The getTitle() and setTitle() functions, and the
334 binding for the \c text property of the Text object will all refer to the \c title
335 property declared in the Displayable component.
336
337 Despite sharing the same name, the two properties are entirely separate.  An
338 onChanged signal handler for one of the properties will not be triggered by
339 a change to the other property with the same name.  An alias to either property
340 will refer to one or the other, but not both.
341
342 \section1 JavaScript Global Object
343
344 QML disallows element, id and property names that conflict with the properties
345 on the global object to prevent any confusion.  Programmers can be confident
346 that \c Math.min(10, 9) will always work as expected!
347
348 See \l {JavaScript Host Environment} for more information.
349
350 */