QML访问嵌套ListModel时报Cannot read property 'days' of undefined如何解决
问题原因
该报错TypeError: Cannot read property 'days' of undefined是链式调用中前置节点返回undefined导致的,核心有两个触发点:
- 初始化时序不匹配
ApplicationWindow初始化时就会执行notesText的绑定逻辑,但此时:
monthlistModel的数据是在自身Component.onCompleted回调中才填充,初始化阶段模型为空,monthlistModel.get()返回undefined- 日历控件
monthofdayCalendar、newdayCalendar、dayList的currentIndex初始值为-1,get(-1)也会返回undefined
- 嵌套数据访问方式错误
你在createDays、createHours中返回的是普通JS数组,并非ListModel实例,只有ListModel才有get()方法,普通数组需要用[]下标访问。
解决步骤
1. 修正嵌套数据访问语法
将链式调用中的.get()替换为数组下标访问[],原错误访问逻辑:
// 错误写法,days、hours为普通数组,不能调用get() monthlistModel.get(monthofdayCalendar.currentIndex).days.get(newdayCalendar.currentIndex).hours.get(dayList.currentIndex).notes
修改为:
// 正确写法,普通数组用[]访问下标 monthlistModel.get(monthofdayCalendar.currentIndex).days[newdayCalendar.currentIndex].hours[dayList.currentIndex].notes
2. 增加空值防护,避免初始化报错
把notesText的绑定改成带合法性校验的函数调用,避免非法索引访问时报错:
ApplicationWindow { id:appWindow width: 1000 height: 600 visible:true flags:Qt.FramelessWindowHint property var monthName:0 // 新增校验函数,每一层访问前先判断合法性 function getCurrentNotes() { // 校验模型是否初始化完成、月份索引是否合法 if (monthlistModel.count === 0 || monthofdayCalendar.currentIndex < 0 || monthofdayCalendar.currentIndex >= monthlistModel.count) { return "" } const monthItem = monthlistModel.get(monthofdayCalendar.currentIndex) // 校验天索引是否合法 if (!monthItem.days || newdayCalendar.currentIndex <0 || newdayCalendar.currentIndex >= monthItem.days.length) { return "" } const dayItem = monthItem.days[newdayCalendar.currentIndex] // 校验小时索引是否合法 if (!dayItem.hours || dayList.currentIndex <0 || dayList.currentIndex >= dayItem.hours.length) { return "" } return dayItem.hours[dayList.currentIndex].notes || "" } property string notesText: getCurrentNotes() // 索引变化时自动更新notesText Connections { target: monthofdayCalendar onCurrentIndexChanged: appWindow.notesText = getCurrentNotes() } Connections { target: newdayCalendar onCurrentIndexChanged: appWindow.notesText = getCurrentNotes() } Connections { target: dayList onCurrentIndexChanged: appWindow.notesText = getCurrentNotes() } // 模型初始化完成后更新一次 Connections { target: monthlistModel onCountChanged: if (count === 12) appWindow.notesText = getCurrentNotes() } Settings { property alias notesText: appWindow.notesText } }
可选优化方案
如果你希望嵌套的days、hours也支持ListModel的特性(比如动态更新、绑定自动刷新),可以修改createDays、createHours函数,返回ListModel实例而非普通数组,修改后原有的.get()访问语法可以保留:
function createDays(dayCount) { let dayModel = ListModel {} for (let i = 0; i < dayCount+1; i++) { dayModel.append({ day: i , hours: createHours() }) } return dayModel } function createHours() { let hourModel = ListModel {} for (let i = 0; i < 25; i++) { hourModel.append({ hour: i, notes: "" }) } return hourModel }
内容的提问来源于stack exchange,提问作者cgiannakidis
相关产品推荐
相关产品推荐

