问题点
qml 页面直接绑定了js数据类型如:object,array,map,weakmap之类子属性更新为什么页面没有刷新
为什么不刷新呢?
a)qml页面绑定的数据源需要携带变更信号如绑定value,必须有valuechanged对应的项变更才会通知页面刷新,而object,array…很明显原生的js库里面没有这个东西
qml支持的刷新
官方文档里面也说了------JavaScript 自动创建未声明的变量是对全局对象的隐式修改,在 QML 中是被禁止的。
比如你使用defineProperty创建的属性就是隐式的修改,是被禁止的
你哪怕创建成功,你修改也不会刷新页面的,而js中object的子属性对于qml而言都是隐式的属性
总而言之,qml不支持隐式属性的页面刷新
那么支持什么数据刷新呢?
支持的数据变更刷新方式-----当然是显式数据:声明给qml知道的数据,通过关键字property声明
property 类型 属性名: 值
很多人就说你讲个狗shit,你懂个屁,误人子弟
我想说兄弟你先别急。
其实兄弟我上面已经说的很明白了,不要以为将一个json数据赋值给property的属性就以为自己的json就是显式属性了,比如
test{
a:1
b:'7777'
}
property var prop: test
修改prop.a = 2 页面不会刷新的,因为test 中的a是没有变更信号通知的
但是 你将prop=其他值,只有值不同他一定刷新
对于qml,想要让他刷新你就得有changed信号
而你要有changed信号你就得通过关键字property声明
解决方案
我从前端获取到的json给qml刷新就没有办法了吗?
我想说qml的属性声明应当是基于基础类型的声明
int real double string bool等
也就是说我们声明一个属性都是基于基础类型的集合或者他本身,
这样才能确保你的qml能够通知页面刷新
数据模型的意义不就是在于此吗?
我们不同的json我们需要创建一个他自己的数据模型放到一个model文件夹里面管理
如
数据模型
这里面的JsonObject ,JsonArray, 请查看我后面的章节会有相关代码
property JsonObject studentObj: JsonObject{
property string name
property int age
property JsonObject klass: JsonObject{
property int studentNum
}
property JsonArray teachers: JsonArray{
delegate: Component{
JsonObject{
property string name
}
}
}
}
json数据执行转化为模型
let obj = Util_Q.extend(studentObj,{
name: "zhangsan",
age: 18,
klass:{
studentNum: 32
},
teachers:[
{name:"lls"},
{name:"zls"},
{name:"bls"}
]
})
util.js
里面含有方法extend
其中Util.isObject 在util.js文件中
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
util_q.js
.import "./core/util.js" as Util
// adapte to qml
function extend(target){
let i,key
for (i = 1; i < arguments.length; i++) {
var source = arguments[i];
if(Util.isArray(source)){
target.clear();
for (key in source) {
if(Util.isObject(source[key])){
target.push(extend(target.delegate.createObject()
,source[key]))
}else{
target.push(source[key])
}
}
}else{
for (key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
if(Array.isArray(source[key])){
extend(target[key],source[key])
}else if(Util.isObject(source[key])){
extend(target[key],source[key])
}else{
target[key] = source[key];
}
}
}
}
}
return target
}
使用到qml视图中
ListView{
height: 40
delegate: Label{text:modelData.name}
model: studentObj.teachers.list()
}
原理很简单:
就是将json数据转成qml中QtObject的所有基础属性
这些基础属性都是经过----property关键字显式声明给qml知道的----
那么他们的变动都会触发各自的changed信号,从而改变页面内容
扩展
JsonObject.qml,JsonArray.qml 请参考第七章内容