最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to call a parent method from kendo template binding? - Stack Overflow

programmeradmin0浏览0评论

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);

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);
Share Improve this question edited Jun 10, 2014 at 15:08 Ovi asked Jun 6, 2014 at 20:50 OviOvi 6048 silver badges16 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 8

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.

发布评论

评论列表(0)

  1. 暂无评论