Reputation: 13
A have template:
<table data-bind="foreach: {data: messages, as: 'message'}">
<tr> <td data-bind="text: $root.go"></td> </tr>
</table>
My js:
function CreateViewModel() {
var self = this;
this.go = ko.computed(function() {
return 'not really important what here for now';
});
}
ko.applyBindings( new MessagesVM );
The context in 'go' while runtime is 'window', I want it to be the current item.
Is it possible?
If I change tmpl line to "<td data-bind="text: go"></td>
" I will have an error ['go' is not defined].
Upvotes: 0
Views: 721
Reputation: 1075855
The context in 'go' while runtime is 'window', I want it to be the current item. Is it possible?
I don't think you can with a computed, no. If you make it a simple function you can: data-bind="text: $root.go.call(message)"
(generically it would be .call($data)
, but since you're naming it in your foreach
):
function MessagesVM() {
var self = this;
this.messages = ko.observableArray([
"Message 1",
"Message 2"
]);
this.go = function() {
return 'this is: "' + this + '"';
};
}
ko.applyBindings(new MessagesVM);
<table data-bind="foreach: {data: messages, as: 'message'}">
<tr>
<td data-bind="text: $root.go.call(message)"></td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
Alternately, if you want some of the functionality of a computed but acting on the individual item, I'd probably use a binding handler:
ko.bindingHandlers.specialText = {
update: function(element, valueAccessor) {
var value = ko.unwrap(valueAccessor());
element.innerHTML = "'value' is " + value;
}
};
function MessagesVM() {
var self = this;
this.messages = ko.observableArray([
"Message 1",
"Message 2"
]);
}
ko.applyBindings(new MessagesVM);
<table data-bind="foreach: {data: messages, as: 'message'}">
<tr>
<td data-bind="specialText: message"></td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
Upvotes: 1
Reputation: 43899
Turn it into a function and pass the context in. As a computed, it has a cached value and so cannot be context-dependent.
function CreateViewModel() {
var self = this;
this.messages = [
'one',
'two'
];
this.go = function(data) {
var context = data;
return 'Context:' + context;
};
}
ko.applyBindings(new CreateViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<table data-bind="foreach: {data: messages, as: 'message'}">
<tr>
<td data-bind="text: $root.go(message)"></td>
</tr>
</table>
Upvotes: 1