如何从kendo模板绑定调用父方法?

时间:2014-06-06 20:50:17

标签: javascript mvvm knockout.js kendo-mvvm

我有以下fiddle。我试图为数组汽车内的每个元素调用父方法lowestMpgMsg。我尝试使用以下绑定而没有运气:

data-bind="text: lowestMpgMsg()"
data-bind="text: parent.lowestMpgMsg()"
data-bind="text: parent().lowestMpgMsg()"
data-bind="text: parent().lowestMpgMsg"

谢谢!

这是我的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>

这是我的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);

1 个答案:

答案 0 :(得分:7)

简短的回答是你没有 - 它自动调用父对象的父方法,让人想起原型链是如何工作的。答案越长,问题中列出的语法就越正确,而且代码与您使用this的方式有一个微妙的错误。

首先,请注意bindings are not javascript。文档中的MVVM概述阐明了您无法在绑定中调用方法,因此括号中的任何内容都不是合法语法。即使你可以,你也必须从汽车实例中调用两次父方法:

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 

这意味着您需要绑定某些内容,例如parent().parent().lowestMpgMsg()

好消息是data-bind="text: lowestMpgMsg"的行为与你想要的一样。它会调用项目的parent().parent().lowestMpgMsg()。要查看基本父链的工作情况,请将模板更改为

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

和模型

    var viewModel = kendo.observable({
        cars: [
            {brand: "Toyota", mpg: 22},
            {brand: "Mini", mpg: 32},
            {brand: "Honda", mpg: 23}
        ],
        lowestMpgMsg: function(e) {       
            return Math.random();
        }
    });

现在,让我们了解你的lowestMpgMsg无效的原因。首先注意该方法会在您的viewmodel上抛出异常,但不会在包装的对象中抛出异常:

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

在绑定期间调用lowestMpgMsg时,this.cars引用与viewModel.cars相同的对象,而instanceof类型kendo.data.ObservableArray则不是sort有一个{{1}}方法。

最后,请确保use a get method for the calculated field,因此MVVM框架知道在依赖关系发生变化时更新它。