0

我正在使用 RPNiemeyer 的 kendo-knockout 库。我有两个嵌套绑定。我从这里使用 preventBindings 技术:

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

我在父 div 上应用绑定,然后阻止嵌套 div 上的绑定。当我单击网格中的行时,我希望触发第二个绑定并弹出打开但没有任何反应。示例代码类似于:Kendo-Knockout:widget observable 中没有填充实际的widget

只有 html 不同(languageDetailsdiv 嵌套在languageListdiv 中):

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

当我在我的应用程序中调试代码时,在languageListdiv 上应用绑定并单击该行以打开弹出窗口时,第二个绑定未应用并且执行未进入函数:

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

这可能意味着第一个应用绑定已应用于两个嵌套 div,而第二个阻止绑定不起作用。这只是我的建议。

这是小提琴:

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 作为一个单独的组件,它可以在同一页面上出现多次。然后,此解决方案将不起作用,因为我将两个组件绑定到的 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 回答