I have an observableArray
of selectable items (in a table). What I'm trying to do is open a modal on click of the table row, populate the modal with the item details, allow editing of the item and then save the changes - reflecting the updated item in the observableArray
. I've got everything else working so far, but can't seem to get the array item to update.
So far I've tried:
observableArray
an observable
.replace
on the array to update the item - this does work, but it just feels wrongI've provided a jsFiddle link above that demonstrates what I'm trying to achieve.
View model and initialization
Feel free to make any suggestions on how I'm initializing self.selectItem
I'm currently in the learning stage of KnockoutJS, and doing so by playing around with mock projects so I'm open to all constructive criticism.
var items = [{
Id: 1,
Text: 'First item'
}, {
Id: 2,
Text: 'Second item'
}];
var viewModel = function (items) {
var self = this;
self.items = ko.observableArray(items);
self.selectedItemId = ko.observable();
self.item = ko.observable();
self.selectItem = function (item) {
for (var i = 0; i < self.items().length; i++) {
if (self.items()[i].Id === self.selectedItemId()) {
self.item(self.items()[i]);
break;
}
}
};
};
ko.applyBindings(new viewModel(items));
Markup bindings
<select data-bind="options: items, optionsCaption: 'Select...', optionsText: 'Text', optionsValue: 'Id', value: selectedItemId, event: { change: selectItem }"></select>
<div data-bind="if: item">
<input type="text" data-bind="value: item().Text" />
</div>
<table>
<thead>
<tr>
<th>Text</th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: $data.Text"></td>
</tr>
</tbody>
</table>
An observableArray just tracks which objects it holds, and notifies listeners when objects are added or removed.
ObservableArray is an array that allows listeners to track changes when they occur. In order to track changes, the internal array is encapsulated and there is no direct access available from the outside. Bulk operations are supported but they always do a copy of the data range.
I have create a new jsFiddle example with an update of items when you change the 'Text' property.
Your problem was the 'items' variable. If you want to update items properties, you have to make them observable :
var observableItems = [
new ItemViewModel(1, "First item"),
new ItemViewModel(2, "Second item")
];
function ItemViewModel(id, text){
var self = this;
self.Id = ko.observable(id);
self.Text = ko.observable(text);
}
Hope it helps !
Your code work fine. All what you need is to update your items
array to have it's property Text
to be observable
var items = [{
Id: 1,
Text: ko.observable('First item')
}, {
Id: 2,
Text: ko.observable('Second item')
}];
And i add small code to check if the selected option is "Select..." then clear the item to hide the input text.
kindly check my Working DEMO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With