I am using prototypejs and knockout in my web project.
First of all let me explain the overall structure.
I have a base class named as userViewModel and an observable variable named accNumber is declared in this class definition.
userViewModel = Class.create(baseViewModel , {
accNumber: ko.observable("")
});
There is another class which is derived from my base class and a computed variable named accNumberComputed is declared in this derived class.
femaleUserViewModel = Class.create(userViewModel , {
accNumberComputed : ko.pureComputed({
read: function () {
return this.accNumber();
},
write: function (value) {
this.accNumber(value);
},
owner: this
})
});
I want to update accNumberComputed variable depends on the accNumber observable variable. So that any modification on the accNumber variable will be tracked on the accNumberComputed variable.
But any this.accNumber()
statement usage returns a
"TypeError: this.accNumber is not a function" error message.
As far as i know an observable variable must be read by using a function call operator.
Could you please enlighten me about this problem.
If you dig a little deeper, you'll find out that in your example this.accNumber
is not only not a function, it's actually undefined
.
The this
in your computed's read
method refers to window
.
I'm not familiar with the prototypejs library, but there's probably a way to get it to bind to the instance correctly.
I had a quick glance at the documentation, and did see a way that resembles how it'd work in a "plain javascript approach". It works like this:
initialize
in prototypejs)This:
var userViewModel = Class.create(baseViewModel , {
accNumber: ko.observable("")
});
becomes:
var userViewModel = Class.create(baseViewModel, {
initialize: function() {
this.accNumber = ko.observable("");
}
});
Not sure if it's the best way of doing it, but can be done like:
var Extended = Class.create(Base, {
initialize: function() {
Extended.superclass.prototype.initialize.call(this);
In your example, this is what you'll get:
var baseViewModel = Class.create({
initialize: function() {
this.base = "base";
}
});
var userViewModel = Class.create(baseViewModel, {
initialize: function() {
this.accNumber = ko.observable("1");
}
});
var femaleUserViewModel = Class.create(userViewModel, {
initialize: function() {
femaleUserViewModel.superclass.prototype.initialize.call(this);
this.accNumberComputed = ko.pureComputed({
read: function() {
return this.accNumber();
},
write: function(value) {
this.accNumber(value);
},
owner: this
})
}
});
var janeDoe = new femaleUserViewModel();
console.log(janeDoe.accNumberComputed());
janeDoe.accNumberComputed(2);
console.log(janeDoe.accNumberComputed());
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>