Reputation: 1
As a beginner in Knockout.js I have a problem with handling data from tables joined by a foreign key.
Let's say we have such a simple code:
function AppViewModel() {
var self = this;
self.users = ko.observableArray([
{id: 0, name: "Willi", surname: "Jederman", meal: {id: 1, name: "Orange", price: 25.00}},
{id: 1, name: "Hans", surname: "Kloss", meal: {id: 2, name: "Carrot", price: 300.00}}
]);
self.meals = ko.observableArray([
{id: 0, name: "Apple", price: 10.00},
{id: 1, name: "Orange", price: 25.00},
{id: 2, name: "Carrot", price: 300.00}
]);
self.addUser = function() {
self.users.push({id: null, name: "", surname: "", meal: {id: 0, name: "Apple", price: 10.00}});
};
self.removeUser = function(user) {
self.users.remove(user);
};
}
ko.applyBindings(new AppViewModel());
The data:
{id: 0, name: "Willi", surname: "Jederman", meal: {id: 1, name: "Orange", price: 25.00}}
is taken from two tables - server returns rows from 'users' and 'meals' tables as one json - these are joined by a foreign key "meal_id" in the 'users' table.
I can also fetch this data as:
{id: 0, name: "Willi", surname: "Jederman", meal_id: 1}
Now I wish to show a simple table with this data:
name | surname | meal name | meal price
where 'meal name' is a select with options taken from 'self.meals' and with current user 'meal.id' selected.
I have a problem with 'meal price' - it should change automatically with 'meal name' select change, but I don't know how to do it.
My 'meal name' select looks like this:
(inside a data-bind="foreach: users":)
<select data-bind="options: $root.meals,
optionsValue: 'id',
optionsText: 'name',
value: meal.id"></select>
I don't know what binding should I give to 'meal price'? I know, that it should start from 'data-bind="text:'...
Thanks for any help.
Upvotes: 0
Views: 542
Reputation: 3938
You need class for user like this
function User(user, root) {
this.id = ko.observable(user.id);
this.name = ko.observable(user.name);
this.surname = ko.observable(user.surname);
this.mealId = ko.observable(user.mealId);
this.root = root;
this.currentMeal = ko.computed(function () {
var mealId = this.mealId();
return ko.utils.arrayFirst(this.root.meals, function(item) {
return item.id === mealId;
});
}, this);
}
Note currentMeal
computed, that finds the meal by it's id
from the root model data.
Сonnect your models with root
parameter
function AppViewModel() {
this.meals = [
{ id: 0, name: "Apple", price: 10.00 },
{ id: 1, name: "Orange", price: 25.00 },
{ id: 2, name: "Carrot", price: 300.00 }
];
this.users = ko.observableArray([
new User({id: 0, name: "Willi", surname: "Jederman", mealId: 1}, this),
new User({id: 1, name: "Hans", surname: "Kloss", mealId: 2}, this)
]);
this.addUser = function() {
this.users.push(new User({id: null, name: "", surname: "", mealId: 0}), this);
};
this.removeUser = function(user) {
this.users.remove(user);
};
}
See fiddle
Upvotes: 1