source: trunk/doc/src/declarative/scope.qdoc@ 1147

Last change on this file since 1147 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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