0

RPNiemeyer剣道ノックアウトライブラリを使用しています。相互にインスタンス化する3つのビューモデルがあります-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ました。グリッドのソースにバインドするときにエラーが剣道ノックアウトライブラリにあると思います。グリッドを削除すると、この行のdivにバインドするノックアウトにエラーがないためです。

ko.applyBindings(parentViewModel, element);

これがこのエラーの本当の理由であり、どうすればこれを修正できますか?親ビューモデルへの参照を削除できないため、ソースデータにバインドするときの剣道ノックアウトの動作を修正したいと考えています。実例の助けがあれば大歓迎です。ありがとう。

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

Niemeyerのコメントごとに更新:

にバインドされたいくつかのプロパティを持つdivがありますFranchiseDetailsViewModel。これらのプロパティの1つは、チェックボックスを表します-名前を付けますisVisible。プロパティがにバインドされた別のdivがありますLanguageDetailsViewModel。これらのプロパティの一部は、のチェックボックスがオンになっている場合にのみ表示されFranchiseDetailsViewModelます。それはfranchise.isVisible本当です。これが私がフランチャイズのリファレンスを必要とする理由です。

私はjavascriptにかなり慣れていないので、プロトタイププロパティを正しく使用していない可能性があります。キーワードを使用してビューモデルをインスタンス化してnewいるときに、プロトタイプに割り当てると、ビューモデルが公開されてマークアップに表示されるため、バインドできることがわかりました。あなたの例から、this.myPropertyもプロパティを公開していることがわかります。私のシナリオに違いがあるかどうかはわかりません。

this.myData.parent = parent;私は自分の問題の解決策として使用することにしました。フィードバックありがとうございます。

4

1 に答える 1

1

上記のコメントに基づく:

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。

通常、オブザーバブルはすべてのインスタンスで共有されるため、プロトタイプにオブザーバブルを配置することは望ましくありません。

于 2012-12-21T20:42:32.027 に答える