Reputation: 1556
Am I missing anything, or is it simply not possible to declare a computed "inline" property like id_and_name
below in my first example?
function viewmodel(){
var self = this;
// adding 'inline' won't work (exception that the functions doesn't exist):
self.person = ko.observable({
id: ko.observable(),
name: ko.observable(),
id_and_name: ko.computed(function(){ return this.id() + this.name(); }, self.person)
});
// this works:
self.person.id_and_name = ko.computed(function(){
return this.id() + this.name();
}, self.person);
}
Upvotes: 0
Views: 193
Reputation: 63739
Well, self.person
is undefined until after the ko.observable
call has returned. The computed
is bootstrapped before that, so it is bootstrapped at a moment when self.person
is still undefined
. You can check it out in the computed
source code file, pretty easy to read actually.
Here's one way to look at that:
function viewmodel() {
var self = this;
self.person = "temp";
self.person = ko.observable({
id: ko.observable(),
name: ko.observable(),
id_and_name: ko.computed(function() {
console.log(this);
return this.id() + this.name();
}, self.person)
});
}
It'll log "temp"
upon initializing, because that's what self.person
is at that time. You cannot change the this
target for the computed read function after it was created.
So nope, what you want can't be done. You need your second solution or a proper view model constructor function*.
* Your top level viewmodel
is already such a constructor function. You could create an inner constructor funciton person
with id
and name
properties, and new
that up, give it a id_and_name
computed that will automatically have the correct this
bound.
Upvotes: 1