I have the following fiddle. I'm trying to call the parent method lowestMpgMsg for each of the elements inside the array cars. I have try using the following bindings with no luck:
data-bind="text: lowestMpgMsg()"
data-bind="text: parent.lowestMpgMsg()"
data-bind="text: parent().lowestMpgMsg()"
data-bind="text: parent().lowestMpgMsg"
Thank you!
Here is my html
<div class="container">
<div id="template-container" data-template="template" data-bind="source: cars"></div>
<script id="template" type="text/x-kendo-template">
<div>
<span data-bind="text: brand"></span> -
<span data-bind="text: mpg"></span> -
<span data-bind="text: lowestMpgMsg()"></span> -
</div>
</script>
and here is my javascript
var viewModel = kendo.observable({
cars: [
{brand: "Toyota", mpg: 22},
{brand: "Mini", mpg: 32},
{brand: "Honda", mpg: 23}
],
lowestMpgMsg: function(e) {
var sorted = this.cars.sort(function(a, b) {
return a.mpg - b.mpg > 0;
});
return e.mpg > sorted[0].mpg ? "no" : "yes";
}
});
kendo.bind($("#template-container"), viewModel);
The short answer is that you don't have to--it calls the parent method on the parent automatically, reminiscent of how the prototype chain works. The longer answer is the correct syntax isn't one listed in your question AND the code has a subtle error with the way you're using this
.
First, notice that bindings are not javascript. The MVVM overview in the documentation clarifies that you cannot invoke methods in bindings, so nothing with parenthesis is going to be legal syntax. Even if you could, you would have to call the parent method twice from a car instance:
var car = viewModel.cars[0];
var cars = car.parent();
var model = car.parent().parent();
var lowestFn = model.lowestMpgMsg.bind(model); //the bind makes this refer to the intended object
This means you would need something to bind to something like parent().parent().lowestMpgMsg()
The good news is that data-bind="text: lowestMpgMsg"
will behave like you want it to. It will call the item's parent().parent().lowestMpgMsg()
. To see the basic parent chain working, changing the template to
<script id="template" type="text/x-kendo-template">
<div>
<span data-bind="text: brand"></span> -
<span data-bind="text: mpg"></span> -
<span data-bind="text: lowestMpgMsg"></span> -
</div>
</script>
and the model to
var viewModel = kendo.observable({
cars: [
{brand: "Toyota", mpg: 22},
{brand: "Mini", mpg: 32},
{brand: "Honda", mpg: 23}
],
lowestMpgMsg: function(e) {
return Math.random();
}
});
Now, let's get to why your lowestMpgMsg
isn't working. Start by noticing that the method throws an exception on your viewmodel, but not in the object that is wrapped:
viewModel.lowestMpgMsg({mpg:15}); //throws exception
var notWrapped = {
cars: [
{brand: "Toyota", mpg: 22},
{brand: "Mini", mpg: 32},
{brand: "Honda", mpg: 23}
],
lowestMpgMsg: function(e) {
var sorted = this.cars.sort(function(a, b) {
return a.mpg - b.mpg > 0;
});
return e.mpg > sorted[0].mpg ? "no" : "yes";
}
}
notWrapped.lowestMpgMsg({mpg:15}); //no exception
When the lowestMpgMsg
is invoked during binding, the this.cars
refers to the same object as viewModel.cars
and is an instanceof
type kendo.data.ObservableArray
, which does not have a sort
method.
Finally, be sure to use a get method for the calculated field, so the MVVM framework knows to update it when dependencies change.
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