I need to set from the main viewmodel a property inside an observable array.
I'm using the classic pre
to debug and display the content of my observable array.
By using types.valueHasMutated()
I can see the applied changes - just only to vm.types
(which wouldn't be the case otherwise).
However, I need to see this changes reflected inside my component.
In my example, when I ckick "Apples", the corresponding input shall be disabled like the one below. Sadly, this is actually not the case.
What I'm doing wrong?
ko.components.register("available-items", {
viewModel: function(params) {
function AvailableItems(params) {
var self = this;
self.params = params;
self.location = "A";
self.types = ko.computed(function() {
var types = self.params.types();
return ko.utils.arrayFilter(types, function(item) {
return item.location == self.location;
});
});
self.addItem = function(data, event) {
self.params.items.addItem(self.location, data.type);
};
}
return new AvailableItems(params);
},
template: '<div>' +
'<h4>Add item</h4>' +
'<ul data-bind="foreach: types">' +
'<li>' +
'<input type="text" data-bind="value: type, enable:available, event: {click: $parent.addItem}" readonly/>' +
'</li>' +
'</ul>' +
'</div>',
synchronous: true
});
var types = [{
type: "Apples",
location: "A",
available: true
}, {
type: "Bananas",
location: "A",
available: false
}];
function Vm(data) {
var self = this;
self.items = ko.observableArray();
self.types = ko.observableArray(ko.utils.arrayMap(data, function(item) {
return item;
}));
self.items.addItem = function(location, type) {
self.items.push({
location: location,
type: type
});
if (location == "A" && type == "Apples") {
self.types()[0].available = false;
self.types.valueHasMutated();
}
};
}
ko.options.deferUpdates = true;
var vm = new Vm(types);
ko.applyBindings(vm);
pre {
position: absolute;
width: 300px;
right: 0;
top: 0;
}
<!DOCTYPE html>
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
</head>
<body>
<div data-bind="component:{name:'available-items',params:vm}"></div>
<ul data-bind="foreach: items">
<li><span data-bind="text: location"></span> - <span data-bind="text: type"></span></li>
</ul>
<pre data-bind="text: ko.toJSON(vm.types, null, 2)"></pre>
</body>
</html>