![](/img/trans.png)
[英]Create exception accessible from both Model and Controller in rails 4
[英]Custom view with model and delegate both accessible from both QML files
雖然我已經想通了,但還是花了很長時間。 如果您知道一個不那么復雜的解決方案 - 請分享。
我想提供一個自定義View
,它適用於任何類型的model
(帶有任意命名的字段):
model: 3
model: [ "red", "yellow", "green" ]
model: [ {color: "red"}, {color: "yellow"}, {color: "green"} ]
model: ListModel{ ListElement{color: "red"}; ListElement{color: "green"} }
QAbstractItemModel
等... 為此,我決定提供一個property Component delegate
,用戶將使用將插入到我的View
深處的可視Item
來填充該屬性。
但是, View
還需要從同一個delegate
訪問一些信息,否則它會促進不必要的代碼重復,或者代理model
的不必要的復雜性。
MyView {
mymodel: ["red", "blue"]
mydelegate: Text {
text: "color=" + modelData.name
must_also_somehow_set_color_of_MyView_element_to: modelData.color
}
}
...其中 MyView 應該是這樣的:
Column {
Repeater {
model: mymodel
delegate: Rectangle {
color: somehow_get_color_from_mydelegate
Text {} // <--- instantiate mydelegate here with data from mymodel
}
}
}
這樣做似乎很容易,但幼稚的嘗試並沒有奏效。 作為答案發布的解決方案對我有用。
訣竅是model
對Repeater
或Instantiator
的delegate
可見,它包含對所述delegate
可見的所有內容,包括index
和modelData
。
所述model
可用作ListModel.append()
的參數以創建具有單個元素的ListModel
。
It can then be assigned as a model
to a Repeater
which will load the delegate
with a copy of all context properties that QML normally derives from the element of View
's model
including index
, modelData
and model
itself.
實例化后, Repeater
/ Instantiator
觸發onItemAdded
/ onObjectAdded
信號,該信號可用作獲取對View
delegate
實例的引用的提示
可以要求View
的用戶在delegate
中提供一個根property
,該屬性將存儲View
可以使用的獲得/計算的值
或者, View
可以包含另一個Repeater
或Instantiator
器,並請求另一個delegate
來獲取它自己需要的值。 或者一個容器類型可以封裝View
的數據和可視的Item
。
例子:
MyView.qml
import QtQuick 2.0
import QtQml.Models 2.1
Column {
property var mymodel
property Component mydelegate
Repeater {
model: mymodel
delegate: Rectangle {
width: childrenRect.width; height: childrenRect.height
//color: model.color //works if "mymodel" has role "color"
property var myitem: null //this will hold instance of mydelegate
color: ( null !== myitem
&& undefined !== myitem.bgcolor )
? myitem.bgcolor : "transparent" //reads property of mydelegate
// <-- mydelegate will be injected here
Repeater {
delegate: mydelegate
model: ListModel{
Component.onCompleted: append(model)
}
onItemAdded: myitem = item
onItemRemoved: myitem = null
}
}
}
}
UsageExamples.qml
import QtQuick 2.0
import QtQuick.Window 2.0
Window{
visible: true
Row {
spacing: 10
MyView {
mymodel: ListModel {
ListElement{ name: "roses"; color: "red"; }
ListElement{ name: "violets"; color: "blue"; }
}
mydelegate: Text {
text: name
property color bgcolor: model.color
}
}
MyView {
mymodel: [{name: "roses", color: "red"}, {name: "violets", color: "blue"}]
mydelegate: Text {
text: modelData.name
property color bgcolor: modelData.color
}
}
MyView {
mymodel: ["red", "blue"]
mydelegate: Text {
text: "color="+modelData
property color bgcolor: modelData
}
}
}
}
我認為你真的在尋找一個加載器來實例化委托,而不是第二個中繼器。 您還可以通過使用別名來簡化一點。 嘗試這樣的事情:
Column {
property alias mymodel: repeater.model
property alias mydelegate: loader.sourceComponent
Repeater {
id: repeater
delegate: Rectangle {
width: childrenRect.width; height: childrenRect.height
color: ( null !== loader.item
&& undefined !== loader.item.bgcolor )
? loader.item.bgcolor : "transparent"
Loader {
id: loader
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.