Home > Enterprise >  Create a binding for a value in ListModel QML
Create a binding for a value in ListModel QML

Time:09-17

I have a ListModel and ListView where I display the notifications a user has. The ListView has an add transition for every time a new notification pops up. Now, I want to add a timestamp (in minutes) to the ListModel to display how old the notification is, but since I add values to the ListModel when a notification is created, I have to manually update the model every minute to change the timestamp, which in turn triggers my add transition. How can I update the timestamp without re-adding the values every time?

property int numNotifications: backend_service.num_notifications

onNumNotificationsChanged: {
    notificationModel.clear()
    for(var x=0; x<numNotifications; x  ) {
           var notif = backend_service.notifications.get(x);
           notificationModel.insert(0, {"name":notif.name, "time":notif.time})
    }
}
        Rectangle {
            height: 500
            width: 0.90 * parent.width
            anchors {
                top: parent
                topMargin: 30
                left: parent.left
                leftMargin: 45
            }
            ListView {
                anchors.fill: parent
                model: notificationModel
                delegate: notificationDelegate
                spacing: 30

                add: Transition {
                    NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 1000 }
                }
            }
        }

        ListModel {
            id: notificationModel
        }

        Component {
            id: notificationDelegate
            Row {
                spacing: 20
                Text { text: name; color: "white" }
                Text { text: time; color: "white" }
            }
        }

time is the measure of how old the notification is in minutes (1 minute, 2 minutes, etc.), I have to update that value. That value is updated in backend_service automatically, but the ListModel holds the old value from when it was first added. I want to update that time value without changing the model. Is there a way to do this without updating the model every time, perhaps by creating a binding? I'm open to other ways of accomplishing this as well.

CodePudding user response:

My recommendation is that the model should hold a fixed timestamp, not a relative one. You can then choose to display it relative to current time in your view (delegate).

property date now: new Date()

Timer {
    running: true
    repeat: true
    interval: 60 * 1000  // Every minute
    onTriggered: {
        now = new Date()
    }
}

Component {
    id: notificationDelegate
    Row {
        spacing: 20
        Text { text: name; color: "white" }
        Text { 
            color: "white"
            text: {
                var diff = now - time

                // Display relative time, something like this...
                if (diff > [1 minute]) {
                    return "1 minute ago"
                } else if (diff > [2 minutes]) {
                    return "2 minutes ago"
                }
                else ... // etc.
            }
        }
    }
}
  • Related