Reputation: 8156
Can a computed variable have properties?
For example, I have user input of room dimensions, and I want them to be put through some scaling logic that something else on the screen needs to read from.
When either Width, Height, or Depth is updated, I need to update ALL of ScaledRoom W/H/D, as there's going to be a fair bit of logic that changes all three values depending on situations.
var MyViewModel = function () {
var self = this;
//Room Dimensions
self.RoomWidth = ko.observable();
self.RoomHeight = ko.observable();
self.RoomDepth = ko.observable();
//basic psuedocode of what I want to achieve... Haven't put in the previously mentioned logic in order to keep it simple
self.ScaledRoom = ko.computed(function () {
this.Width = self.RoomWidth * 10;
this.Height = self.RoomHeight * 15;
this.Depth = self.RoomDepth * 11;
return this;
});
};
In the html, i'd like to be able to databind to ScaledRoom.Width() for example
What's the best way to do this?
Upvotes: 0
Views: 218
Reputation: 7958
Create a separate model for ScaledRoom:
var ScaledRoom = function () {
var self = this;
self.Width = ko.observable(0);
self.Height = ko.observable(0);
self.Depth = ko.observable(0);
}
Then you can have a computed observable which changes the values on the object. The if statement first checks if there is an object. If there is no object then it's created.
var ViewModel = function () {
var self = this;
self.RoomWidth = ko.observable(0);
self.RoomHeight = ko.observable(0);
self.RoomDepth = ko.observable(0);
self.ScaledRoom = ko.computed(function () {
var scaledRoom;
if (!self.ScaledRoom) {
scaledRoom = new ScaledRoom();
}
else {
scaledRoom = self.ScaledRoom();
}
scaledRoom.Width(self.RoomWidth() * 10);
scaledRoom.Height(self.RoomHeight() * 15);
scaledRoom.Depth(self.RoomDepth() * 11);
return scaledRoom;
});
};
View:
<div>
Room Width: <input type="text" data-bind="value: RoomWidth"/>
</div>
<div>
Room Height: <input type="text" data-bind="value: RoomHeight"/>
</div>
<div>
Room Depth: <input type="text" data-bind="value: RoomDepth"/>
</div>
<div data-bind="with: ScaledRoom">
<div data-bind="text: Width"></div>
<div data-bind="text: Height"></div>
<div data-bind="text: Depth"></div>
</div>
Demo: http://jsfiddle.net/bmk3eo4m/
Upvotes: 1