I have this model, a Foo
have many FooItem
. How can I add an object to a FooItem
?
I have this code, you can suggest or even erase the whole code that works best for this scenario
var Foo = function (selected) {
this.id = ko.observable();
this.name = ko.observable();
this.fooItems = ko.observableArray([]);
this.isSelected = ko.computed(function() {
return selected() === this;
}, this);
};
var FooItem = function () {
this.id = ko.observable();
this.selectedItemId = ko.observable();
this.selectedName = ko.observable();
this.remarks = ko.observable();
};
var foosFromDb = [{ id: 1, name: 'foo1' },
{ id: 2, name: 'foo2' },
{ id: 3, name: 'foo3' },
{ id: 4, name: 'foo4' }];
var fooItemsFromDb = [
{ id: 1, fooItem: 'fooItem1' },
{ id: 2, fooItem: 'fooItem2' },
{ id: 3, fooItem: 'fooItem3' },
{ id: 4, fooItem: 'fooItem4' },
{ id: 5, fooItem: 'fooItem5' },
];
var vm = (function () {
var
foos = ko.observableArray([]),
fooItemsList = ko.observableArray([]),
loadFoos = function() {
for(var i = 0; i < foosFromDb.length; i++) {
foos.push(new Foo(selectedFoo)
.id(foosFromDb[i].id)
.name(foosFromDb[i].name));
}
selectFoo(foos()[0]);
},
loadFooItemsList = function() {
for(var i = 0; i < fooItemsFromDb.length; i++) {
fooItemsList.push({ id: fooItemsFromDb[i].id, name: fooItemsFromDb[i].fooItem });
}
},
selectedFoo = ko.observable(),
selectFoo = function(item) {
selectedFoo(item);
},
newFoo = function(item) {
var id = foos().length + 1;
var aFoo = new Foo(selectedFoo)
.id(id)
.name('');
foos.push(aFoo);
selectFoo(aFoo);
},
addFooItem = function(item){
console.log(item); // In here I think I am getting the Selected Foo.
};
return {
foos: foos,
loadFoos: loadFoos,
newFoo: newFoo,
selectedFoo: selectedFoo,
selectFoo: selectFoo,
loadFooItemsList: loadFooItemsList,
fooItemsList: fooItemsList,
addFooItem: addFooItem
};
}());
vm.loadFoos();
vm.loadFooItemsList();
ko.applyBindings(vm);
.container {
float: left;
width: 200px;
height: 250px;
border: 1px solid #ccc;
}
.selected {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="container">
<a href="#" data-bind="click: newFoo">New Foo</a>
<table>
<tr>
<th>Foo Id</th>
<th>Foo Name</th>
</tr>
<tbody data-bind="foreach: foos" style="cursor: pointer">
<tr data-bind="click: $root.selectFoo, css: { selected: isSelected }">
<td data-bind="text: id"></td>
<td data-bind="text: name"></td>
</tr>
</tbody>
</table>
</div>
<div data-bind="with: selectedFoo">
<div class="container">
<label>Id</label><br /><input type="text" data-bind="value: id" /><br />
<label>Name</label><br /><input type="text" data-bind="value: name" /><br />
</div>
<div class="container">
<label>Foo Item</label><br /><select data-bind="options: $root.fooItemsList,
optionsText: 'name',
optionsValue: 'id'"></select><br />
<label>Remarks</label><br /><input type="text" /><br />
<a href="#" data-bind="click: $root.addFooItem">Add Foo Item</a>
</div>
<div class="container">
<table>
<thead>
<tr>
<th>FooItem</th>
<th>Remarks</th>
</tr>
</thead>
</table>
</div>
</div>
<div style="clear: both"></div>
<pre data-bind="text: ko.toJSON($root.selectedFoo, null, 2)"></pre>
When I click
the Add Foo Item I would it like to be populate the table (in the farthest right) of what was entered in the fields and also populating the fooItems
property of Foo
.
I have this fiddle for reference
Suggestions, tips or any coding practice is welcome. Any help would be much appreciated. Thanks
EDIT I ended up posting the whole view model. Which is wrong
You are missing a number of things that are necessary to hook everything up. Your
select
was not bound to anything, and you did not have an observable for it to bind to. I added aselectedItem
member toFoo
for this.The
optionsValue
for the select I reverted to be the item being selected, because I don't want to look it up. The value isn't aFooItem
, but is a simple object with id and name. InaddFooItem
, I create a newFooItem
from the object data and push it onto thefooItems
list.The table body wasn't defined, so I set that up to display. For some reason, saving a remark causes all the previously saved remarks to update. I don't know why that is, but I find the whole construction a bit hard to follow.