How to use a one way binding in knockout
If you execute a property OR drop the observable in a knockout binding it becomes a one way/read only. So in the following model for example:
class Person {
constructor(data) {
// Method 1: Consume observable using ()
this.firstName = ko.observable(data.firstName);
// Method 2: Omit the observable
this.flatFirstName = data.firstName;
this.lastName = ko.observable(data.lastName);
this.fullName = ko.computed(() => `${this.firstName()} ${this.lastName()}`);
}
}
const me = new Person({
firstName: "John",
lastName: "Smith"
});
ko.applyBindings(me);
I can make FirstName a one way/read only property simply by executing it in the binding:
<input data-bind="value: firstName()">
<input data-bind="value: flatFirstName">
<input data-bind="value: lastName">
<label data-bind="text: fullName"></label>
So now the first input only gets the value and can not set it but the second input will have two way binding and will update the LastName property.
Hope this helps.
class Person {
constructor(data) {
// Method 1: Consume observable using ()
this.firstName = ko.observable(data.firstName);
// Method 2: Omit the observable
this.flatFirstName = data.firstName;
this.lastName = ko.observable(data.lastName);
this.fullName = ko.computed(() => `${this.firstName()} ${this.lastName()}`);
}
}
const me = new Person({
firstName: "John",
lastName: "Smith"
});
ko.applyBindings(me);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<input data-bind="value: firstName()">
<input data-bind="value: flatFirstName">
<input data-bind="value: lastName">
<label data-bind="text: fullName"></label>
The one way binding means : modifications on UI (typing in the input) are 'applied' to the view model. But if you change the viewModel (by code) the UI wont be refreshed.
If you need to refresh the UI by code (js), you have to use an observable.
As you can see in this fiddle, if you click on the 'Change by code' button the view model will be changed but not the UI.
var viewModel = {
firstName: 'Fred',
test: function () {
alert(viewModel.firstName);
},
change: function () {
viewModel.firstName = "new Value";
}
};
See fiddle.
I hope it helps.