---
title: "Data Binding"
description: ""
---
Scripting allows you to read, modify, and subscribe to changes in View Model properties,
as well as create new View Model instances at runtime.
For a conceptual overview of View Models and how they drive your graphic,
see [View Models & Data Binding](/editor/data-binding/overview).
## View Models
There are three ways that a script can gain access to a View Model and its properties:
- Accessing View Models through [Context](#context)
- Data binding a [View Model as an input](#view-models-as-inputs)
- Data [binding view model properties to inputs](#binding-inputs)
### Context
The `init` lifecycle function includes a `context` parameter that gives you access
to your view models. This allows you to read values (strings, enums, lists, etc.), set values,
fire triggers, listen for triggers, and subscribe to value changes.
In addition to view models, [Context](/scripting/api-reference/interfaces/context) gives you access to named assets and update scheduling.
```lua {5, 8, 11, 12}
type MyNode = {}
function init(self: MyNode, context: Context): boolean
-- Get the view model from the node's immediate context.
local vmi = context:viewModel()
-- Get the root view model
local rootVmi = context:rootViewModel()
-- Get the view model from the parent node.
local parentDC = dc:parent()
local parentVmi = dc:viewModel()
end
return function(): Node
return {
init = init,
}
end
```
### View Models as Inputs
You can create a [Script Input](/scripting/script-inputs) that can be bound to a view model. This allows you to read values (strings, enums, lists, etc.), set values, fire triggers, listen for triggers, and subscribe to value changes.
```lua {3,7,15}
type MyNode = {
-- This input expects a view model instance of type Character
character: Input
}
function init(self: MyNode, context: Context): boolean
local vmi = self.character
end
return function(): Node
return {
init = init,
-- Initialize with `late()` so the value
-- can be provided by the editor at runtime.
character = late(),
}
end
```
For a detailed explanation, see [View Models Inputs](/scripting/script-inputs#view-model-inputs).
### Binding Inputs
If you only need to read, not set view model properties, you can data bind view model property values to script inputs.
For more information see [Data Binding Inputs](/scripting/script-inputs#data-binding-inputs).
### Nested View Models
To reference a nested view model, use `getViewModel`.
```lua
local vmi = context:viewModel(),
local dateVmi = vmi:getViewModel('dateViewModel')
```
## Reading and Setting Properties
The following methods allow you to reference view model properties:
- [getNumber](/scripting/api-reference/interfaces/view-model#getnumber)
- [getTrigger](/scripting/api-reference/interfaces/view-model#gettrigger)
- [getString](/scripting/api-reference/interfaces/view-model#getstring)
- [getBoolean](/scripting/api-reference/interfaces/view-model#getboolean)
- [getColor](/scripting/api-reference/interfaces/view-model#getcolor)
- [getList](/scripting/api-reference/interfaces/view-model#getlist)
- [getViewModel](/scripting/api-reference/interfaces/view-model#getviewmodel)
- [getEnum](/scripting/api-reference/interfaces/view-model#getenum)
```lua {5,8,11,15,18}
local vmi = context:viewModel()
if vmi then
-- Get a reference to the score property from the view model
local score = vmi:getNumber('score')
if score then
-- Read the score
print(score.value)
-- Set the score
score.value = 100
end
-- Get a reference to the myTrigger property from the view model
local myTrigger = vmi:getTrigger('myTrigger')
if myTrigger then
-- Fire the trigger
mytrigger:fire()
end
end
```
## Listening for Property Changes
### Add a Listener
Use `addListener` to listen for triggers or changes to view model properties.
```lua {17,23}
type MyNode = {}
function handleHoursChanged()
print('hours changed!')
end
function handleTriggerFired()
print('Fire!')
end
function init(self: MyNode, context: Context): boolean
local vmi = context:viewModel()
local hours = vm:getNumber('hours')
if hours then
-- handleHoursChanged is called whenever the hours value changes
hours:addListener(handleHoursChanged)
end
local trigger = vm:getTrigger('triggerProperty')
if trigger then
-- handleTriggerFired is called whenever the trigger is fired
trigger:addListener(handleTriggerFired)
end
return true
end
return function(): Node
return {
init = init,
}
end
```
### Remove a Listener
Always remove listeners when they are no longer needed to avoid memory leaks.
```lua highlight={17}
type MyNode = {}
function init(self: MyNode, context: Context): boolean
local vmi = context:viewModel()
if not vmi then
print('No view model found')
return false
end
local hours = vmi:getNumber('hours')
if hours then
local function handleHoursChanged()
print('hours changed!')
-- Remove the event listener
hours:removeListener(handleHoursChanged)
end
-- handleHoursChanged is called whenever the hours value changes
hours:addListener(handleHoursChanged)
end
return true
end
return function(): Node
return {
init = init,
hours = late(),
trigger = late(),
}
end
```
## Creating a View Model Instance
Coming soon