1

我有一个使用一些 jQuery 插件运行 Knockout 的应用程序,这里有问题的是 jQuery UI 选项卡。

通过一些搜索,我发现 jQuery 的数据插件保存的数据($(someElt).data())一直存在,直到我通过 Knockout 应用绑定。

之后,jQuery持有的数据就没有了,这让插件认为它没有初始化。

让这个陌生人感到奇怪的是,我的外部选项卡集(页面选项卡和页面选项卡的一个窗格中的选项卡)工作正常。
然而,内部标签有这个问题。

选项卡的任何一个容器都没有直接绑定,尽管两者内部和外部都有一些元素(尽管两者都不应该导致任何实际删除 DOM 元素)。

有什么想法吗?

编辑:这是我创建的一个测试用例(我使用的是 jQuery 1.9.2 和 Knockout 2.2.1):

<div id="OutterTabContainer">
  <ul>
    <li>
      <a href="#OutterTab1">Outter Tab 1</a>
    </li>
    <li>
      <a href="#OutterTab2">Outter Tab 2</a>
    </li>
  </ul>
  <div id="OutterTab1">
    This is the first tab.
    <div data-bind="visible: test2">This should be invisible</div>

  </div>
  <div id="OutterTab2">
    This is the second tab.
    <div data-bind="text: test1()"></div>

    <div data-bind="with: testObj()">
      <div id="InnerTabContainer">
        <ul>
          <li>
            <a href="#InnerTab1">Inner Tab 1</a>
          </li>
          <li>
            <a href="#InnerTab2">Inner Tab 2</a>
          </li>
        </ul>
        <div id="InnerTab1">
          This is the first of the inner tabs.
        </div>
        <div id="InnerTab2">
          This is the second of the inner tabs.
          @*<div data-bind="text: innerTest()"></div>*@
        </div>
      </div>
    </div>

  </div>
</div>

<script type="text/javascript">
  (function($, ko, undefined) {
    var outterTabs = $("#OutterTabContainer"),
        innerTabs = $("#InnerTabContainer"),
        viewModel = {
          test1: ko.observable("test 1"),
          test2: ko.observable(false),
          testObj: ko.observable({
            innerTest: ko.observable("inner")
          })
        };

    //creating tabs, works fine
    outterTabs.tabs();
    innerTabs.tabs();

    setTimeout(function() {
      //simulating an ajax success callback
      ko.applyBindings(viewModel);
      innerTabs.tabs("select", 1);
    }, 1000);

  })(jQuery, ko);
</script>

在创建它时,我发现罪魁祸首是选项卡 2 中的“with”绑定。我仍然不确定为什么该绑定会导致此问题,因此我仍在寻找适当的解决方法。我想如果推送到了,我可以将内部选项卡初始化推迟到绑定视图模型之后。

编辑 2:我一直在查看淘汰赛源代码,看起来 with 绑定运行与 if 和 ifnot 绑定相同的代码。看起来绑定到 with 的元素变成了虚拟元素,据我所知,这些虚拟元素在应用绑定时被销毁并重新创建,因此元素本身(以及所有子元素,包括选项卡容器)将与之前的元素不同。我猜这就是数据不再存在的原因(因为它是由 dom 节点保存的)。

4

2 回答 2

1

根据我的建议,您可以尝试这样的事情(现已测试!):

ko.bindingHandlers["tab"] = {
   init: function(element) {
       $(element).tabs();
   }
};

进而:

<div id="InnerTabContainer" data-bind="tab: $data">

编辑:事实证明,绑定需要一些数据,即使您没有使用它。

这是一个小提琴

于 2013-01-24T15:23:37.037 回答
0

我在使用手风琴时遇到了同样的问题(来自 jQuery UI),结果证明 Benjamin 关于 'with' 处理程序是正确的,导致元素认为它没有被初始化(谢谢你的帮助)。

我测试了Matt提出的解决方案,解决问题的不是呈现给元素的$data,而是绑定完成后内部选项卡的初始化。顺便说一句,这是我迄今为止找到的唯一解决方案。这是解决此问题的唯一方法吗?

编辑:经过一番挖掘,我发现 IE8 不能正确处理“with”处理程序(虚拟元素),删除它可以解决问题。

于 2013-02-25T09:14:09.003 回答