1

いくつかの jQuery プラグインを使用して Knockout を実行しているアプリケーションがあります。ここで問題となっているのは jQuery UI タブです。

($(someElt).data())いくつかの検索を通じて、knockout を介してバインディングを適用するまで 、jQuery のデータ プラグインによって保持されているデータが存在することがわかりました。

その後、jQuery が保持するデータがなくなるため、プラグインは初期化されていないと認識します。

これを奇妙にしているのは、私の外側のタブのセット (ページのタブと、ページのタブのペインの 1 つにタブがあります) が正常に動作することです。
ただし、内側のタブにはこの問題があります。

どちらのタブのコンテナーにも直接バインディングはありませんが、両方のコンテナーの内側と外側にいくつかの on 要素があります (どちらも 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 に答える