aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc
diff options
context:
space:
mode:
authorSze Howe Koh <szehowe.koh@gmail.com>2014-05-14 22:33:34 +0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-05-16 03:45:07 +0200
commitea401b8ebff8ee58f6db7b1c623883a72365a2b8 (patch)
tree9156aee24509c117d111ba41c6fa66067ab5ea33 /src/qml/doc
parentd3064953f12d780e06578d97990533c93b3c2781 (diff)
Doc: Describe property bindings in terms of relationships
- This patch aims to help readers think about bindings more "declaratively" by introducing a new (albeit very leaky) level of abstraction: Treat bindings as finitary relations, rather than mere JavaScript expressions. - In essence, property bindings are for describing relationships between properties. The fact that the QML engine reactively updates a property's value when its dependencies change, and the fact that arbitrarily complex expressions are valid bindings, are simply implementation details. - Discourage the use of side effects in property bindings. They are not essential for the main purpose of property bindings, they break the finitary relation model, and their use can reduce code readability/maintainability/toolability. - Discourage complex property bindings for similar reasons. Change-Id: I5a0a03bd02768d4c504797a0f86569f3ac066e96 Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Diffstat (limited to 'src/qml/doc')
-rw-r--r--src/qml/doc/src/cppintegration/exposecppattributes.qdoc5
-rw-r--r--src/qml/doc/src/javascript/expressions.qdoc32
-rw-r--r--src/qml/doc/src/javascript/topic.qdoc13
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/scope.qdoc8
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc68
5 files changed, 78 insertions, 48 deletions
diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
index 86715e93f1..f02c3da6af 100644
--- a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
+++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
@@ -148,8 +148,9 @@ Text {
For maximum interoperability with QML, \b {any property that is writable should
have an associated NOTIFY signal} that is emitted whenever the property value
has changed. This allows the property to be used with \l{Property
-Binding}{property binding}, which is an essential feature of QML that enables
-specific values to be updated whenever an associated property changes.
+Binding}{property binding}, which is an essential feature of QML that enforces
+relationships between properties by automatically updating a property whenever
+any of its dependencies change in value.
In the above example, the associated NOTIFY signal for the \c author property is
\c authorChanged, as specified in the Q_PROPERTY() macro call. This means that
diff --git a/src/qml/doc/src/javascript/expressions.qdoc b/src/qml/doc/src/javascript/expressions.qdoc
index c33daf7acc..79c11b3ac5 100644
--- a/src/qml/doc/src/javascript/expressions.qdoc
+++ b/src/qml/doc/src/javascript/expressions.qdoc
@@ -57,30 +57,28 @@ QML \l{QML Object Types}{object types} defined in \l{QML Documents}
{QML documents} can make use of JavaScript expressions which implement program
logic. There are four ways that JavaScript can be used in a QML document:
-\list
- \li \l{Property Attributes}{properties} can be
- assigned \l{Property Binding}{bindings} which are defined with
- JavaScript expressions, and which are automatically evaluated by the
- \l{QQmlEngine}{QML engine} when any properties accessed in the binding
- change, in order to ensure always-up-to-date property values. Binding
- expressions can also perform function evaluation as an explicit side
- effect
- \li \l{Signal Attributes}{signal handlers} can be defined
+\list 1
+ \li Relationships between \l{Property Attributes}{properties} are described
+ using JavaScript expressions in \l{Property Binding}{property bindings}.
+ When any of a property's \e dependencies change, the property is
+ automatically updated too, according to the specified relationship.
+ \li \l{Signal Attributes}{Signal handlers} can be defined
which are automatically evaluated when the object emits the associated
- signal
- \li \l{Method Attributes}{custom methods} can be defined
- in QML files as JavaScript functions
+ signal.
+ \li \l{Method Attributes}{Custom methods} can be defined
+ in QML files as JavaScript functions.
\li JavaScript files providing functions and variables can be
\l{Importing JavaScript Resources in QML}{imported} in a QML
- document
+ document.
\endlist
\section2 Property Bindings
-During startup, the QML engine will set up and initialize the property
-bindings. The JavaScript conditional operator is a valid property binding.
+In the following example, the \l Rectangle's \c color depends on the
+\l MouseArea's \c pressed property. This relationship is described using a
+conditional expression:
\qml
import QtQuick 2.0
@@ -100,7 +98,9 @@ Rectangle {
In fact, any JavaScript expression (no matter how complex) may be used in a
property binding definition, as long as the result of the expression is a
-value whose type can be assigned to the property.
+value whose type can be assigned to the property. This includes side effects.
+However, complex bindings and side effects are discouraged because they can
+reduce the performance, readability, and maintainability of the code.
There are two ways to define a property binding: the first (and most common)
is, as previously shown, in a \l{QML Object Attributes#Value Assignment on Initialization}
diff --git a/src/qml/doc/src/javascript/topic.qdoc b/src/qml/doc/src/javascript/topic.qdoc
index 40602b5017..f341816201 100644
--- a/src/qml/doc/src/javascript/topic.qdoc
+++ b/src/qml/doc/src/javascript/topic.qdoc
@@ -38,14 +38,11 @@ JavaScript to quickly develop both user-interfaces and application logic.
\section1 JavaScript Expressions
-QML has a deep JavaScript integration, and allows
-\l{Signal Attributes}{signal handlers}
-and \l{Method Attributes}{methods}
-to be defined in JavaScript. One of the other fundamental concepts of QML is
-the ability to bind property values to the result of complex expressions which
-can include properties from other objects. These
-\l{Property Binding}{property bindings}
-are JavaScript expressions.
+QML has a deep JavaScript integration, and allows \l{Signal Attributes}
+{signal handlers} and \l{Method Attributes}{methods} to be defined in JavaScript.
+Another core feature of QML is the ability to specify and enforce relationships
+between object properties using \l{Property Binding}{property bindings}, which
+are also defined using JavaScript.
See the documentation page titled
\l{qtqml-javascript-expressions.html}{JavaScript Expressions in QML Documents}
diff --git a/src/qml/doc/src/qmllanguageref/documents/scope.qdoc b/src/qml/doc/src/qmllanguageref/documents/scope.qdoc
index 845ca30b4f..af59afe1fb 100644
--- a/src/qml/doc/src/qmllanguageref/documents/scope.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/scope.qdoc
@@ -105,11 +105,9 @@ ListView {
\section1 Binding Scope Object
-Property bindings are the most common use of JavaScript in QML. Property
-bindings associate the result of a JavaScript expression with a property of an
-object. The object to which the bound property belongs is known as the binding's
-scope object. In this QML simple declaration the \l Item object is the
-binding's scope object.
+An object which has a \l{Property Binding}{property binding} is known has the
+binding's \e{scope object}. In the following example, the \l Item object is
+the binding's scope object.
\code
Item {
diff --git a/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc b/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc
index 653fe2391e..8faa3220fa 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc
@@ -30,32 +30,44 @@
\title Property Binding
\brief binding object properties
-To make the fullest use of QML and its built-in support for implementing dynamic object behavioral changes, most QML objects will use \e {property binding}. This is a core feature of QML that allows objects to automatically update their properties in response to changing attributes in other objects or the occurrence of some external event.
+An object's property can be assigned a static value which stays constant until it
+is explicitly assigned a new value. However, to make the fullest use of QML and its
+built-in support for dynamic object behaviors, most QML objects use \e {property bindings}.
-When an object's property is assigned a value, it can either be assigned a static value, or \e bound to a JavaScript expression. In the first case, the property's value will not change unless a new value is assigned to the property. In the latter case, a \e {property binding} is created and the property's value is automatically updated by the QML engine whenever the value of the evaluated expression changes.
+Property bindings are a core feature of QML that lets developers specify relationships
+between different object properties. When a property's \e dependencies change in
+value, the property is automatically updated according to the specified relationship.
+Behind the scenes, the QML engine monitors the property's dependencies (that is,
+the variables in the binding expression). When a change is detected, the QML engine
+re-evaluates the binding expression and applies the new result to the property.
\section1 Overview
-To create a property binding, a property is assigned an expression that evaluates to the desired value. At its simplest, an expression may simply be a reference to another object's property. Take the following example, where the blue \l Rectangle's \c height is bound to the height of its parent:
+To create a property binding, a property is assigned a JavaScript expression that
+evaluates to the desired value. At its simplest, a binding may be a reference to
+another property. Take the following example, where the blue \l Rectangle's height
+is bound to the height of its parent:
\qml
Rectangle {
width: 200; height: 200
Rectangle {
- width: 100; height: parent.height
+ width: 100
+ height: parent.height
color: "blue"
}
}
\endqml
-Whenever the \c height of the parent item changes, the \c height of the blue rectangle will update to be of the same value.
+Whenever the height of the parent rectangle changes, the height of the blue
+rectangle automatically updates to be of the same value.
-Furthermore, a binding can contain any valid JavaScript expression or
-statement, as QML uses a standards compliant JavaScript engine. Below are
-valid bindings that could be substituted for the \c height binding from the
-above example:
+A binding can contain any valid JavaScript expression or statement, as QML uses
+a standards compliant JavaScript engine. Bindings can access object properties,
+call methods and use built-in JavaScript objects such as \c Date and \c Math.
+Below are other possible bindings for the previous example:
\code
height: parent.height / 2
@@ -74,16 +86,16 @@ height: {
height: someMethodThatReturnsHeight()
\endcode
-Whenever the value of \c parent.height changes, the QML engine will re-evaluate the above expression and assign the blue rectangle's \c width property with the appropriate updated value.
-
-Bindings can access object properties, call methods and use built-in JavaScript objects such as \c Date and \c Math. Here is an example with various valid bindings:
+Below is a more complex example involving more objects and types:
\qml
Column {
+ id: column
width: 200
height: 200
Rectangle {
+ id: topRect
width: Math.max(bottomRect.width, parent.width/2)
height: (parent.height / 3) + 10
color: "yellow"
@@ -103,15 +115,33 @@ Column {
}
\endqml
-While syntactically bindings can be of arbitrary complexity, if a binding starts to become overly complex - such as involving multiple lines, or imperative loops - it may be better to refactor the component entirely, or at least factor the binding out into a separate function.
+In the previous example,
+\list
+\li \c topRect.width depends on \c bottomRect.width and \c column.width
+\li \c topRect.height depends on \c column.height
+\li \c bottomRect.color depends on \c myTextInput.text.length
+\endlist
+
+Syntactically, bindings are allowed to be of arbitrary complexity. However, if
+a binding is overly complex - such as involving multiple lines, or imperative
+loops - it could indicate that the binding is being used for more than describing
+property relationships. Complex bindings can reduce code performance, readability,
+and maintainability. It may be a good idea to redesign components that have
+complex bindings, or at least factor the binding out into a separate function.
\keyword qml-javascript-assignment
\section1 Creating Property Bindings from JavaScript
-Once a property has been bound to an expression, the property is set to be automatically updated as necessary. However, be aware that if the property is later assigned a static value from a JavaScript statement, this will remove the binding.
+A property with a binding is automatically updated as necessary. However, if the
+property is later assigned a static value from a JavaScript statement, the binding
+will be removed.
-For example, the \c height of the \l Rectangle below is initially bound to be twice its \c width. However, when the space key is pressed, the \c height value is changed to be three times its \c width. At this point, the \c height is assigned the currently evaluated result of \c width*3 and \e {the height will no longer be automatically updated whenever the width changes}. The assignment of the static value removes the binding.
+For example, the \l Rectangle below initially ensures that its \c height is always
+twice its \c width. However, when the space key is pressed, the current value
+of \c {width*3} will be assigned to \c height as a \e static value. After that,
+\e {the \c height will remain fixed at this value, even if the \c width changes}.
+The assignment of the static value removes the binding.
\qml
import QtQuick 2.0
@@ -127,7 +157,10 @@ Rectangle {
}
\endqml
-If the intention is to remove the binding, then this is not a problem. However if the intention is to create a new binding of \c width*3 then the property must be assigned a Qt.binding() value instead. This is done by passing a function to Qt.binding() that returns the desired result:
+If the intention is to give the rectangle a fixed height and stop automatic
+updates, then this is not a problem. However, if the intention is to establish
+a new relationship between \c width and \c height, then the new binding
+expression must be wrapped in the Qt.binding() function instead:
\qml
import QtQuick 2.0
@@ -143,7 +176,8 @@ Rectangle {
}
\endqml
-Now when the space key is pressed, a new binding of \c width*3 is assigned, instead of simply removing the initial binding.
+Now, after the space key is pressed, the rectangle's height will continue
+auto-updating to always be three times its width.
\section2 Using \c this with Property Binding