Kendo-Knockout:对网格源数据应用绑定时的最大调用堆栈大小错误

时间:2012-12-21 15:39:01

标签: knockout.js kendo-ui

我正在使用RPNiemeyer kendo-knockout库。我有三个相互实例化的视图模型 - FranchiseDetailsViewModel实例化LanguageListViewModel,它实例化LanguageDetailsViewModel。最后一个视图模型LanguageDetailsViewModel需要引用父FranchiseDetailsViewModel,因为它的功能取决于它。

HTML:

<div data-viewId="languageList" >
    <div id="languageList" data-bind="with: viewModel">
        <div id="languageListGrid" data-bind="kendoGrid: { data: languageViewModels, columns: [ 
                { 
                    field: 'Language', 
                    title: 'Language',
                    width: 50
                }

                ], 
            scrollable: false, sortable: true, pageable: false }" style="height: 380px">

        </div>
    </div>
</div>​

的javascript

$(function () {

    var FranchiseDetailsViewModel = function () {
        var 
            self = this,
            initialize = function () {
                self.languagesInfoViewModel(new LanguageListViewModel(self));
                var parentViewModel = ({ viewModel: self.languagesInfoViewModel });
                var element = $('div[data-viewId="languageList"')[0];
                ko.applyBindings(parentViewModel, element);
            };

        FranchiseDetailsViewModel.prototype.languagesInfoViewModel = ko.observable();
        initialize();
    };

    var LanguageListViewModel = function (franchise) {
        var 
            self = this,
            initialize = function () {
                var languageViewModel = new LanguageDetailsViewModel(franchise);
                self.languageViewModels.push(languageViewModel);
            };
        LanguageListViewModel.prototype.languageViewModels = ko.observableArray([]);
        initialize();
    };

    var LanguageDetailsViewModel = function (franchise) {
        LanguageDetailsViewModel.prototype.Language = ko.observable("English");
       LanguageDetailsViewModel.prototype.franchise = franchise;
    };

    var initialize = new FranchiseDetailsViewModel();
});​

当网格绑定到源数据时,对父视图模型的引用会导致某种不定式循环。我收到Maximum call stack size exceeded错误。我相信当绑定到网格源时,错误发生在kendo knockout库中,因为如果我删除了网格,那么在此行上绑定到div的敲除没有错误:

ko.applyBindings(parentViewModel, element);

这是导致此错误的真正原因吗?如何解决此问题?我无法删除对父视图模型的引用,所以我希望在绑定到源数据时修复kendo-knockout行为。任何有关工作示例的帮助将不胜感激。感谢。

http://jsfiddle.net/5Zkyg/43/

根据Niemeyer的评论更新:

我有一个div,其中一些属性绑定到FranchiseDetailsViewModel。其中一个属性代表一个复选框 - 将其命名为isVisible。我有另一个div,其属性绑定到LanguageDetailsViewModel。仅当选中FranchiseDetailsViewModel的复选框时,其中一些属性才可见。那是franchise.isVisible是真的。这就是我需要特许经营参考的原因。

我对javascript很新,也许我没有正确使用prototype属性。当我使用new关键字实例化我的视图模型时,我发现当将它分配给原型时,它们变为公共的并且在标记中可见,因此我可以绑定它们。从您的示例中我看到this.myProperty也使该属性公开。我不确定我的情况是否存在差异。

我决定使用this.myData.parent = parent;作为我问题的解决方案。非常感谢您的反馈。

1 个答案:

答案 0 :(得分:1)

基于上述评论:

一个选择是“隐藏”特许经营权,以便Knockout不会递归地试图解开它。你可以通过使它成为函数或可观察的属性(这是一个函数)来做到这一点。

有几种方法可以做到这一点:

var Child = function(parent) {

    //use parent directly from the argument passed to the constructor. available as part of the closure.
    this.myHandler = function() {
        parent.log();
    };        

    this.myData = ko.observable();

    //reference as a sub-observable. you can bind against myData.parent, but it will disappear when doing ko.toJS/ko.toJSON
    this.myData.parent = parent;


    //similar to sub-observable.  hide the actual value behind an empty function.  It will not be found when doing ko.toJS/ko.toJSON.
    this.parent = function() { };
    this.parent.value = parent;  
};

示例:jsfiddle.net/rniemeyer/uSpZB。

通常你不想在原型上放置observable,因为它们将被所有实例共享。