0

RPNiemeyer の kendo-knockout ライブラリを使用しています。ネストされたバインディングが 2 つあります。ここから preventBindings 手法を使用しています。

http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html

親 div にバインディングを適用してから、ネストされた div でのバインディングを防止しています。グリッドの行をクリックすると、2 番目のバインドがトリガーされてポップアップが表示されると予想されますが、何も起こりません。コード例は次のコードに似ています: Kendo-Knockout: widget observable is notfilled with the actual widget

html のみが異なります ( languageDetailsdiv は div にネストされていlanguageListます):

<div data-viewId="languageList">
  <div id="languageList" data-bind="with: viewModel">
    <div id="languageListGrid" data-bind="kendoGrid: { data: languageViewModels, columns: [ 
                { 
                    template: '<a href=\'\' data-bind=\'click: function() { onLanguageSelected(&quot;#=Language#&quot;) }\'>#=Language#</a>', 
                    field: 'Language', 
                    title: 'Language',
                    width: 50
                }

                ], 
            scrollable: false, sortable: true, pageable: false }, preventBinding: true"
    style="height: 380px"></div>
    <div data-bind="preventBinding: true">
      <div data-viewid="languageDetails">
        <div id="languageDetails" data-bind="with: viewModel" class="hidden">
          <form id="languageDetailsForm" action="" style="font-family: Trebuchet MS, Verdana, Helvetica, Sans-Serif;">
              <div data-bind="kendoWindow: {isOpen: isOpen, title:'Language', width: 400, height: 200, modal: true, widget: popUpWindow }">test
                  <button id="cancelLanguage" class="k-button" data-bind="click: cancelLanguage">Cancel</button>
              </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

バインディングが div に適用されているときにアプリケーションのコードをデバッグlanguageListし、行をクリックしてポップアップを開くと、2 番目のバインディングは適用されず、実行は関数に入りません。

if (!elementIsBoundNew(element)) {
      var parentViewModel = {
        viewModel: viewModel
      };

これは、最初の適用バインディングが 2 つのネストされた div に適用され、2 番目の防止バインディングが機能していないことを意味している可能性があります。これは私の提案です。

ここにフィドルがあります:

http://jsfiddle.net/PVMjy/4/

どんな助けでも大歓迎です。ありがとう!

RP Niemeyer のコメントによる更新:

あなたのソリューションは、私がフィドルで提供したサンプルでは機能しますが、私のアプリケーションでは機能しません。私の実際のシナリオでは、グリッドから selectedLanguage を使用して、既存のビューモデルのリストから言語ビューモデルを見つけ、それを selectedLanguageViewModel オブザーバブルに割り当てます。つまり、selectedLanguageViewModel が空になることはありません。これは私の実際のアプリケーションのコードです:

LanguageListViewModel.prototype.onLanguageSelected = function (selectedLanguage) {
            var languageViewModel = getLanguageViewModel(selectedLanguage);
            self.selectedLanguageViewModel(languageViewModel);
            utils.applyBindings(self.selectedLanguageViewModel, languageDetailsElement);
            self.selectedLanguageViewModel().openPopUp(false);
            //createTreeView();
        };

ここで機能させるために行ったことは、バインドした div の elementid を配列に保存することです。次に、バインディングを適用する必要がある場合は、要素が配列内にあるかどうかを確認し、そうでない場合はバインディングを適用します。

var applyedBindingsElements = [];

  var applyBindings = function (viewModel, elementId) {
    if($.inArray(elementId, applyedBindingsElements) == -1)
    {
      var element = $('div[data-viewId="' + elementId + '"]')[0];
      var parentViewModel = { viewModel: viewModel };
      ko.applyBindings(parentViewModel, element);

      applyedBindingsElements.push(elementId);
    }
  };

私の将来の計画は、languageList を、同じページに複数回表示できる別のコンポーネントとして使用することです。次に、2 つのコンポーネントをバインドする div elementIds が同じ名前 ( "languageList") を持つため、このソリューションは機能しません。そのため、別の解決策を考える必要があります。しかし、これは近いうちに別の質問をするトピックであり、フィードバックをいただければ幸いです。ありがとう!

このトピックに関する私のソリューションをいじる:

http://jsfiddle.net/PVMjy/6/

4

1 に答える 1

1

問題はko.dataFor、DOM を検索してその値を見つけることです。したがって、実際にはバインディングがスキップされた領域の外に出て、ビュー モデル全体を見つけます。そのため、ポップアップを開こうとすると、バインディングが既に適用されているかどうかのガードがヒットします。

バインディング チェックを削除し、ボタンが最初にクリックされたときにバインディングをポップアップ領域に適用するために、いくつかの小さな変更を加えました。

基本的に、すでにバインドされているチェックを削除した後のこのコード:

self.onLanguageSelected = function (selectedLanguage) {
  if (!self.selectedLanguageViewModel()) {
      applyBindings(self.selectedLanguageViewModel, "languageDetails");
  }

  self.selectedLanguageViewModel(self.languageViewModels()[0]);
  self.selectedLanguageViewModel().openPopUp();
};

サンプル: http://jsfiddle.net/rniemeyer/8hzzn/

これはうまくいきますか?

于 2013-01-10T14:49:25.873 に答える