[Development] Namespacing QML context properties

Alan Alpert 416365416c at gmail.com
Mon Dec 9 09:00:34 CET 2013


On Sun, Dec 8, 2013 at 11:28 PM, Alberto Mardegan
<mardy at users.sourceforge.net> wrote:
> On 12/09/2013 12:54 AM, Alan Alpert wrote:
>> On Sun, Dec 8, 2013 at 5:38 AM, Alberto Mardegan
>> <mardy at users.sourceforge.net> wrote:
> [...]
>> What do you mean "current context"? The problem you seem to be hitting
>> is that there is another symbol in the current context that you want
>> to avoid, so that it finds a symbol higher up the tree. That would
>> mean something like engine.rootContext(), but I don't think that would
>> make sense in QML.
>
> I don't really want the engine.rootContext(), but actually
> engine.contextForObject(this). Please have a look at this example, and
> suppose that I want to use this as a delegate in a ListView, in order to
> provide a different delegate for each element in the list, depending on
> some property in the model:
>
> Item {
>     ListView {
>         model: ...
>         delegate: loader
>     }
>     Component {
>         id: delegate1
>         Rectangle { color: model.color; ... }
>     }
>     Component {
>         id: delegate2
>         Text { text: model.text; ... }
>     }
>     Loader {
>         id: loader
>         // property variant model: model
>         sourceComponent: model.someProperty ? delegate1 : delegate2
>     }
> }
>
> Now, if I don't remove the comment, the actual delegates loaded by the
> Loader (delegate1 and delegate2) won't see the "model" property; but if
> I uncomment the line, it won't work either, because inside the Loader's
> definition the property named "model" will obscure the context property
> having the same name.
> How would you solve this (without of course renaming variables or moving
> components around: suppose that I have no control over the listview or
> delegates' code)?
>
> And another simpler case, this:
>
> Item {
>     ListView {
>         model: ...
>         delegate: ComboBox {
>             text: model.displayName
>         }
>     }
> }
>
> And suppose that a certain point the authors of the ComboBox element
> change it by adding a "model" property to it. That would break the code
> above, because "model" wouldn't refer anymore to the "model" injected by
> the ListView, but to the new ComboBox property!
> But if you had a way to select your local context with some prefix, no
> breakage could ever happen:
>
> Item {
>     ListView {
>         model: ...
>         delegate: ComboBox {
>             text: qmlContext.model.displayName
>         }
>     }
> }
>
> I hope that the question is now clearer. :-)

Question does seem a bit clearer. But I think the answer is the same -
ListView shouldn't be using context properties anymore. Well, it's
worthwhile for the convenience here but maybe add an attached property
reference as well for those cases needing more precision:

Item {
    ListView {
        model: 3
        delegate: ComboBox {
            text: ListView.modelData.displayName //unambiguous*
        }
    }
}

*not enforced by the language to be unambiguous like Singletons, but
the conflicting case is left as an exercise to the reader ;)

--
Alan Alpert



More information about the Development mailing list