diff options
author | Bea Lam <bea.lam@nokia.com> | 2011-02-09 05:03:53 (GMT) |
---|---|---|
committer | Bea Lam <bea.lam@nokia.com> | 2011-02-09 05:03:53 (GMT) |
commit | 3ebbb660d6f0c29b438f49dc8187b1b353ee1b8a (patch) | |
tree | 0540d465bd107dd0ce0fcc423dc959cbe787954f /doc/src | |
parent | a78f6b1718b8285cb65ae989a070bf8703746b5d (diff) | |
download | Qt-3ebbb660d6f0c29b438f49dc8187b1b353ee1b8a.zip Qt-3ebbb660d6f0c29b438f49dc8187b1b353ee1b8a.tar.gz Qt-3ebbb660d6f0c29b438f49dc8187b1b353ee1b8a.tar.bz2 |
Fix docs for variant and list basic types
Make it clear that QML properties never store JavaScript object data,
and that inefficient serialization must be performed when JavaScript
objects are copied to QML properties.
Task-number: QTBUG-16624
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/declarative/basictypes.qdoc | 183 |
1 files changed, 84 insertions, 99 deletions
diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc index 463e4a3..eac509e 100644 --- a/doc/src/declarative/basictypes.qdoc +++ b/doc/src/declarative/basictypes.qdoc @@ -400,14 +400,11 @@ \c child1, \c child2 and \c child3 will be added to the children list in the order in which they appear. - List \l {Adding Properties}{properties} can be created as a - \c variant type, or as a \c list<Type> type, where \c Type is the - type of the object in the list: + List \l {Adding Properties}{properties} can be declared as \c list<Type> + type, where \c Type is the type of the object in the list: \qml Item { - property variant values: [ 10, 20, 'abc', 'xyz' ] - property list<Rectangle> rects: [ Rectangle { width: 100; height: 100}, Rectangle { width: 200; height: 200} @@ -415,136 +412,124 @@ } \endqml - A \c variant list can contain values of any of the \l {QML Basic Types}{basic QML types} - such as numbers, strings, etc. while a \c list<Type> list can only contain values - that match (or are derived from) the specified \c Type. + A list property can only contain values that match (or are derived from) the + specified \c Type. - A list property can be cleared by setting it to an empty list: + While the \c rects property can be reassigned to a different list value (including + an empty list), its individual values cannot be modified. See the \l variant type + documentation for details. - \qml - Item { - children: [] - } - \endqml + \sa {QML Basic Types} +*/ + +/*! + \qmlbasictype variant + \ingroup qmlbasictypes - A list property cannot be modified in any other way. Items cannot be dynamically added to - or removed from the list through JavaScript operations; any \c push() operations on the - list only modify a \e copy of the list and not the actual list. (These current limitations - are due to restrictions on \l {Property Binding} where lists are involved.) + \brief A variant type is a generic property type. - You can, however, modify a copy of the list and then reassign the property to the modified - value. Other options are to create an array object from within a \c .js JavaScript file, - or implement a custom list element in C++. Here is a QML element that modifies the list in a - JavaScript file: + A variant is a generic property type. A variant type property can hold + any of the \l {QML Basic Types}{basic type} values: - \table - \row - \o \qml - // QML - import "script.js" as Script - Item { - Component.onCompleted: { - Script.addItem('abc') - console.log("Added:", Script.getList()[0]) - } + property variant aNumber: 100 + property variant aString: "Hello world!" + property variant aBool: false } \endqml - \o - \code - // script.js - var myArray = new Array() + The \c variant type can also hold: - function getList() { - return myArray - } - - function addItem(item) { - myArray.push(item) - } - \endcode - \endtable - - However, note that a JavaScript list should not be used as a QML \c property value, - as the property is not updated when the list changes. + \list + \o An array of \l {QML Basic Types}{basic type} values + \o A map of key-value pairs with \l {QML Basic Types}{basic-type} values + \endlist - \sa {QML Basic Types} -*/ + For example, below is an \c items array and an \c attributes map. Their + contents can be examined using JavaScript \c for loops. Individual array + values are accessible by index, and individual map values are accessible + by key: + \qml + Item { + property variant items: [1, 2, 3, "four", "five"] + property variant attributes: { 'color': 'red', 'width': 100 } -/*! - \qmlbasictype variant - \ingroup qmlbasictypes + Component.onCompleted: { + for (var i=0; i<items.length; i++) + console.log(items[i]) - \brief A variant type is a generic property type. + for (var prop in attributes) + console.log(prop, "=", attributes[prop]) + } + } + \endqml - A variant is a generic property type. A variant type property can hold any of the - \l {QML Basic Types}{basic type} values: + While this is a convenient way to store array and map-type values, you + must be aware that the \c items and \c attributes properties above are \e not + QML objects (and certainly not JavaScript object either) and the key-value + pairs in \c attributes are \e not QML properties. Rather, the \c items + property holds an array of values, and \c attributes holds a set of key-value + pairs. Since they are stored as a set of values, instead of as an object, + their contents \e cannot be modified individually: \qml Item { - property variant aNumber : 100 - property variant aString : "Hello world!" - property variant aList : [ 1, 2, "buckle my shoe" ] + property variant items: [1, 2, 3, "four", "five"] + property variant attributes: { 'color': 'red', 'width': 100 } + + Component.onCompleted: { + items[0] = 10 + console.log(items[0]) // This will still be '1'! + attributes.color = 'blue' + console.log(attributes.color) // This will still be 'red'! + } } \endqml - The \c variant type can also hold a \e copy of a JavaScript object. For example, the - \c animal property below defines a JavaScript object defined with JSON notation. The - object's properties and values can be examined using the standard JavaScript syntax, - as shown in the \c Component.onCompleted handler. + Additionally, since \c items and \c attributes are not QML objects, changing + their individual values do not trigger property change notifications. If + the above example had \c onNumberChanged or \c onAnimalChanged signal + handlers, they would not have been called. If, however, the \c items or + \c attributes properties themselves were reassigned to different values, then + such handlers would be called. + + One way to "update" the contents of an array or map is to copy the property + to a JavaScript object, modify the copy as desired, and then reassign the + property to the updated copy. Note, however, that this is not efficient. + In the example below, which reassigns the \c attributes property, the \e entire + set of key-value pairs must be serialized and deserialized every time it is + copied between a JavaScript object and a QML property: \qml Item { - property variant animal : { 'type': 'bird', 'species': 'galah', 'age': 7 } + property variant attributes: { ''color': 'red', 'width': 100 } Component.onCompleted: { - for (var attribute in animal) - console.log(attribute, "=", animal[attribute]) + // Change the value of attributes.color to 'blue': + var temp = attributes // copy all values to 'temp' + temp.color = 'blue' + attributes = temp // copy all values back to 'attributes' } } \endqml - It must be noted that the \c animal property holds a \e copy of the defined object, and - not the object itself. (This is true even if the property refers to an object defined in - some JavaScript file; the property will hold a copy of the object, and not the actual - object.) The property essentially holds a copy of the contents within the object. This - has several implications: + Since this operation is inefficient, if a list or map should be modifiable, + it is better to use alternative approaches. For example, you could implement + a custom C++ list element, or write to a JavaScript object defined from + within a JavaScript file. - \list - \o Changes to any of the property's values (for example, the \c animal.type value - above) only modify the \e copy of the object, not the object itself. You can, however, - modify a copy of the object and then reassign the property to the modified value. - \o Because the property only holds a copy of the object, \l{Property Binding}{bindings} to - any of the property's individual values are not updated until the whole property is - reassigned to a new value. For example: - - \qml - Item { - property variant animal : { 'type': 'bird', 'species': 'galah', 'age': 7 } - - Text { text: "Animal species: " + animal.species } - - Component.onCompleted: { - animal.species = 'kookaburra' // this has no effect on the displayed text - - var newObj = animal - newObj.species = 'kookaburra' - animal = newObj // this will update the displayed text - } - } - \endqml - \o Since the object values are copied, it does not hold any reference to the original - object, and extra data such as the object's JavaScript prototype chain is lost in the - process. - \endlist + JavaScript programmers should also note that when a JavaScript object is + copied to an array or map property, the \e contents of the object (that is, + its key-value properties) are copied, rather than the object itself. The + property does not hold a reference to the original JavaScript object, and + extra data such as the object's JavaScript prototype chain is also lost in + the process. \sa {QML Basic Types} */ - /*! \qmlbasictype vector3d \ingroup qmlbasictypes |