Create a reactive, observable variable in Knockout.js
Let’s add a new input field to a webpage. Under an <h2>
tag, create a new input tag with the id
of "sku"
, the name
of "sku"
, and the type
of "text"
. Then, set "data-bind"
equal to "value: sku"
.
Normally, we would assign the value to a value
attribute. However, with Knockout, we use value
within data-bind
.
Now, let’s change the data-bind
on the <div>
back to text
and update the default value for sku
back to ABC123
.
When you refresh the page, you will see ABC123
within the text input box and also within the <div>
. However, if you try to update it, you will notice that the value within the <div>
is not updating. This is because we are using a standard string value here and not an observable.
Using Observables for Dynamic Updates
Anytime you need the data on the page to automatically and dynamically react to a changing value, you must use what’s called an observable. An observable listens for changes and automatically emits those changes to anything that is listening for that value, such as any value within a data-bind
attribute.
Importing the Knockout Library
To use observables, first import the Knockout library by importing the ko
string and assign it to the ko
variable. Then, wrap the value of your string with ko.observable()
.
After saving the file and refreshing the page, you will notice that the value in the <div>
automatically re-renders when you change the input value and click outside of the input box. Note that you need to click outside the input text field, or blur it, in order for changes to be rendered.
Using the textInput
Binding
Text inputs are a bit tricky to deal with, and Knockout actually created a special binding for text inputs. Just like we used html
for our data-bind
, update the <input>
data-bind
attribute to use textInput
rather than value
. The textInput
binding is a special Knockout data binding meant just for input elements with the type
of text
.
Now, when you refresh the page and update the input value, you can see that the value within the <div>
updates as you type.
We want to add a placeholder to an <input>
DOM element. To do this, let’s go back to our view model and create another property named placeholder
. We will set this equal to a Knockout observable, and its value will be “Example: 24-MB01”. This is just an example SKU to let the user know what they can type in the <input>
box.
Updating the Template
Now let’s add this to the template. Within data-bind
, we can actually add in multiple calls to helpers. A placeholder
is an attribute on an <input>
field. So normally, when we add one in, we will do so like this: placeholder="my placeholder"
. However, since we are adding this within data-bind
, we will actually have to add in another property named attr
, and then an object. Within this object is where we will define our attributes. Instead of defining placeholder
outside, we will define it within the object. Then we’ll use a colon, and then the value that we want to assign it to, which will be placeholder
. This is the attribute, and this is the attribute value coming from the view model.
If we refresh our page and take a look at this text input and remove everything here, we will see the value of the placeholder. Everything is working as expected.
Observables and Performance
Note that there is something different about this though. This value for placeholder
is not being changed by the user, nor will it ever be changed. It’s not being modified by user input, and nothing within this component or anything externally will ever change it. Even though this is used on the frontend, there’s actually no reason to make this observable. To fix this, all we will do is remove this wrapper to ko.observable()
.
Observables are powerful, but you need to be responsible about their usage. When an observable is defined, Knockout initializes that as a function to track changes, and this contains a certain amount of processing overhead. Because of this, you need to be very conscious about what is defined as an observable and what’s not. A good rule to follow is that if a value changes by user input or programmatically, and you need to be able to react to those changes being made, an observable is totally okay. If a property value really never changes, or you don’t need the view to re-render based on those changes, there is no need to make it an observable.