访问由 Loader 加载的 ListView 委托的成员

Accessing members of ListView delegate which is loaded by Loader

ListView {
    id: listView
    model: someModel {}
    delegate: Loader {
        id: delegateLoader
        source: {
            var where;
            if(model.type === 1) {
                where = "RadioQuestion.qml";
            }
            else
                where = "TextQuestion.qml";
            if(delegateLoader.status == Loader.Ready) {
                delegateLoader.item.question= model.question;
            }

            return Qt.resolvedUrl(where);
        }
}

我使用 ListView 向用户展示了一些问题。但是我无法访问Loader加载的delegate成员。

RadioQuestion.qml 有单选按钮和文本只是文本字段。我只想在按下提交按钮后获得所有答案,但我不知道如何在代表之间遍历。

也许我构建这个结构的方法是错误的。因此,我愿意寻求更好的解决方案。

您的 question 已经通过模型公开,因此您的委托应直接绑定到它,因此假设 question 是模型的 属性:

// from inside the delegate
question: delegateRootId.ListView.view.model.question

或者假设该问题是列表元素角色:

// from inside the delegate
question: model.question

如果您足够小心,不要在委托 question 中命名 属性 从而掩盖模型角色,您可以简单地:

// from inside the delegate
questionSource: question

更不用说,如果您的模型 "scheme" 是已知的,并且假定您将拥有 question 角色并且该角色将显示在委托中,您甚至不需要在委托中需要任何额外的 属性 开始,您可以将实际项目直接绑定到问题,例如:

// from inside the delegate
Text { text: question }

这就是真正需要的。

或者,您可以使用 BindingConnections 元素或简单的信号处理程序来延迟操作,直到加载程序实际完成加载。例如:

delegate: Loader {
        source: Qt.resolvedUrl(model.type === 1 ? "RadioQuestion.qml" : "TextQuestion.qml")
        onStatusChanged: if (status === Loader.Ready) if (item) item.question= model.question
}
Button {
    text: "Submit answers"
    onClicked: {
          for(var child in listView.contentItem.children) {
              var c = listView.contentItem.children[child].item;
              if(typeof c !== "undefined")
                   console.log(c.answer)
          }
    }
 }

您可以像这样获取加载程序委托的属性。我们使用“undefined”检查,因为 contentItem 的 children 中有一个 object 未定义。那是列表中的第二个 object,我不知道为什么。