# Models and views Use a model with QML change notifications when the view must react to mutation. A plain JavaScript array is suitable for static data, while `ListModel` or a `QAbstractItemModel` supports observable changes. ```qml import QtQuick import QtQuick.Controls ListModel { id: tasks ListElement { title: "Review"; done: false } } ListView { model: tasks clip: true delegate: CheckDelegate { required property int index required property string title required property bool done width: ListView.view.width text: title checked: done onToggled: tasks.setProperty(index, "done", checked) } } ``` Use required delegate properties for roles and `index` because this is explicit and visible to tooling. Do not retain model objects or delegate instances after a delegate leaves the view. `ListView` creates delegates around its viewport rather than all rows at once. Delegate instance reuse is optional and controlled by `reuseItems`; never rely on delegate-local state surviving. Put durable row state in the model. Use `Repeater` when every delegate should be instantiated as a child of its parent. Use a view when content can exceed the viewport or delegate population must stay bounded. Measure before making fixed item-count rules.