我有一个ListView,它显示来自API的一些数据。在我的列表项中,我需要有两个不同的组件树,具体取决于该行的数据。更具体地说,如果行具有相关联的图像,我需要以特定方式显示带有标签的图像。如果它没有图像,那么我想只显示一个标签,以不同的方式排列。对我来说,这听起来像我想创建两个不同的组件,并动态选择要包含的组件。
它目前看起来像这样,缩写形式:
ListItem.Empty {
id: matchItem
property string team1Name
property string team2Name
property string team1Logo
property string team2Logo
width: parent.width
Item {
id: team1Info
width: parent.width*0.3
anchors {
left: parent.left
top: parent.top
bottom: parent.bottom
}
Item {
anchors.fill: parent
anchors.margins {
top: units.gu(2)
bottom: units.gu(2)
}
Image {
id: team1LogoImage
source: team1Logo
width: parent.width
height: units.gu(5)
fillMode: Image.PreserveAspectFit
anchors.horizontalAlignment: parent.horizontalCenter
}
Label {
text: team1Name
anchors.horizontalAlignment: Text.Center
}
}
}
// Some more elements and a repeat of the above for the second team
}
问题是,如果team1Logo
或team2Logo
不是有效的网址,例如团队没有徽标,则图片组件会失败。
我想做的主要是:
if (team1Logo === "") {
Label {
// Stuff to make it look good without an image
}
} else {
Image {
source: team1Logo
}
Label {
// Stuff
}
}
但据我所知,这不是QML的工作原理。
我已经看了Loader
组件,看起来它可能符合要求,因为我可以在加载器上设置source
属性时使用条件,但我不能让它工作。有谁知道如何实现我所描述的目标?
答案 0 :(得分:6)
事实证明,实施Loader
非常简单。例如:
Item {
id: team1Info
Loader {
id: team1ItemLoader
property string name: model.team1Name
property string logo: model.team1Logo
source: (logo) ? "TeamLogoItem.qml" : "TeamItem.qml"
}
}
在此示例中,name
和logo
随后可在TeamLogoItem.qml
或TeamItem.qml
内作为属性使用。
答案 1 :(得分:1)
@TommyBrunn的答案仅在TeamItem.qml
未定义您要传入的任何property
时才有效。这意味着:
property alias
或者,您可以使用setSource()
将Loader
传递给已加载组件的属性值:
// ### TeamItem.qml (and TeamLogoItem.qml, similarly)
Label {
property alias name: text
property string logo: "qrc:/images/logos/dummy.png"
}
// ### main.qml
Item {
id: team1Info
Loader {
Component.onCompleted: {
var qml = model.team1Logo ? "TeamLogoItem.qml" : "TeamItem.qml";
setSource( qml, { name:model.team1Name, logo:model.team1Logo } )
}
}
}
您也可以选择在 - 例如传递不同的属性值。不会将徽标传递给TeamItem.qml - 基于您正在加载的QML。它们不必具有相同的界面。