component loaded with Loader inside a delegate, how to access model?
-
Inside a delegate that has a Loader, how the component loaded by Loader can access the model?
ComponentBase.qml:
Item { ... property Component insideDelegateComponent ... ListView { ... delegate: Item { ... Loader { sourceComponent: insideDelegateComponent } ... } } ... }
ComponentPaintDelegate.qml
Text { text: model.name }
DrawView.qml
ComponentBase { insideDelegateComponent : ComponentPaintDelegate { ... } }
Gives the error: Cannot read property 'name' of undefined
-
Well, the problem is the model's roles aren't visible from the loader inside the delegate. Here's a code snippet where I've shown properties trick.
Does it fix the issue?
import QtQuick 2.7 Item { width: 640 height: 480 ListModel { id: peopleModel ListElement { name: "Samantha"; age: "21" } ListElement { name: "Joe"; age: "33" } ListElement { name: "Alex"; age: "32" } } Column { anchors.fill: parent Repeater { anchors.fill: parent model: peopleModel Loader { sourceComponent: aDelegate onLoaded: { item.name = name; item.age = age; } } } } Component { id: aDelegate Text { property string name property int age x: 5 height: 15 text: name + "," + age } } }
-
Loader creates an extra context for the dynamically instantiated item. Consequently, if I remember correctly, a property defined in the Loader element itself is visible to the loaded item. The styling of Qt Quick Controls 1.x is based on this technique.
Loader { property string modelName: model.name sourceComponent: exampleComponent } Component { id: exampleComponent Text { text: modelName } }
-
@jpnurmi Yes, you are right. That's even better!
import QtQuick 2.7 Item { width: 640 height: 480 ListModel { id: peopleModel ListElement { name: "Samantha"; age: "21" } ListElement { name: "Joe"; age: "33" } ListElement { name: "Alex"; age: "32" } } Column { anchors.fill: parent Repeater { anchors.fill: parent model: peopleModel Loader { sourceComponent: aDelegate property string modelName: name property int modelAge: age } } } Component { id: aDelegate Text { x: 5 height: 15 text: modelName + "," + modelAge } } }
-
With a little bit of trickery, using the same technique you should be able to expose 'model' as is to the loaded item:
delegate: Item { property var itemModel: model // read 'model' from the delegate's context width: loader.width height: loader.height Loader { id: loader property var model: parent.itemModel // inject 'model' to the loaded item's context sourceComponent: exampleComponent } } Component { id: exampleComponent Text { text: model.name } }