2011-09-11 5 views
6

私はknockoutを使ってjQueryUIのタブを追加/削除しようとしていますが、運がなかった。 私のビューモデルは、Effectオブジェクトの配列です。私は、タブの追加/タブのコントロールから削除されたいオブジェクトを追加/ビューモデルから削除されます。knockout JSを使用してjQueryUIタブを追加または削除する方法は?

は、ここで私はあなたがタブを追加しようとすると、それは壊れます JSFiddle example

を行うために探しているものを示しているJSFiddle誰かが始めたと私は更新されます。私は、私が思うタブコントロールを破壊/再作成することができる新しいカスタムバインディングを持つテンプレートバインディングを組み合わせる必要があると思います。私は大いに助けていただければ幸いです。ありがとう!

答えて

0

ほとんどの場合、モデルが変更されるたびにタブインターフェイスを再描画する必要があります。また

、タブ<ul>に固有のIDを追加します(私はノックアウトでイベントをオフに解雇するかどうかはわからないが、私

$("#tabs").tabs(); 

を呼び出し、たび

<ul id="tabs"> 

モデルの変更をドキュメント内にあることを確認してください)

0

私は非常に似た問題を抱えていました。私は、子ビューモデルのトップレベルの観測可能な配列がタブとして表され、各タブが孫のデータのマークアップをレンダリングする深いビューモデルのグラフを持っています。もともと私はKnockoutが作成した後で、マークアップをタブーにするためにjQueryのUIタブを使っていました。

これらのタブ付きビューモデル/ドメインオブジェクトを追加、削除、複製する機能があります。 jQuery UIのタブでは、破棄を呼び出してから再構築する必要がありました。重複の場合は、選択したインデックスを最初に格納し、レクレーション後にそのインデックス+ 1を選択して新しく作成したタブを選択する必要がありました。

しかし、私はMVVMをUIのドライバとしてより完全に受け入れ、jQueryのタブを完全に取り除き、自分のタブヘッダーとタブコンテンツ要素をKnockoutビューモデルの「isSelected」観測可能プロパティにバインドしました。私はこれをもっときれいにすることができ、より柔軟なやり方を見出し、タブのマークアップ/ CSSがシンプルでエレガントであることが判明しました。

また、isSelectedプロパティは、タブごとに<div class="child" data-bind="if: isSelected">のようなものを指定することで、バインディングの効率を向上させることもできます。以前は(恐らく)ノックアウトは、不可視タブのすべてのバインディングを不必要に処理していました。

これは私が現在自分のUIに一般的にアプローチしようとしているところです。バインディングの使用を可能な限り直接手続き型UIのものを避けています。

3

私はこの問題を、私が使い始めたソリューションの新しいテイクで更新すると思いました。以前はRP Niemeyerのフィドルhttp://jsfiddle.net/rniemeyer/dsKbH/を、KO observableArrayにバインドされたjQuery UIタブを動的に追加/削除するための基礎として使用していました。

私は、A)setTimeout()延期、およびB)アップデートがトリガーされるたびに、タブウィジェットを破棄して再作成することに関連して、アプリ内のいくつかの問題に対して立ち上がりました。だから私はこれらの問題を避ける別のアプローチを思いついた、そしてIMHOはよりエレガントなテクニックです。

http://jsfiddle.net/LatencyMachine/XJPJZ/

キーアイデアは、「タブパネル」と呼ばれる非常に単純なカスタム結合し、あなたのタブパネルのコンテンツのdiv要素に結合し、対応するウィジェットを導入することです。 KOがobservableArrayに基づいてこれらのdivを作成して削除すると、tabPanelバインディングはjQueryUI.tabsを "refresh"メソッドを使用して更新します。これは、コンテナ要素のバインディングで(そして適切なタイミングで)更新するためにタブを取得しようとするよりもずっとスムーズに動作します。フィドルから

関連するコード

/** 
KO Binding handler for a tabPanel div. Use this on divs that can appear/disappear and/or have their id change 
depending upon an observable, usually an observableArray. 
*/ 
ko.bindingHandlers.tabPanel = { 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {   
     $(element).tabPanel(ko.toJS(valueAccessor())); 
    } 
}; 

/** 
This widget facilitates jQuery UI tabs that appear and disappear dynamically, usually as a result of MVVM like Knockout 
Whenever this widget is created, the containing jQuery UI 'tabs' widget is refreshed so that it picks up the new tab 
or drops the removed one. 
This also facilitates dealing with id rename 'ripple' that occurs whenever a tab is removed due to the splice of an 
observable array. 
*/ 
$.widget("bw.tabPanel", { 
    options: { 
     id: null 
    }, 

    _create: function() { 
     this.element.hide(); 
     this.tabsElement = this.element.closest(".ui-tabs");   

     if(this.options.id) { 
      this.element.attr({id: this.options.id}); 
     } 
     this.refreshTabs(); 
    }, 

    _destroy: function() { 
     if(this.options.id) { 
      this.element.attr({id: ""}); 
     } 
     this.refreshTabs(); 
    }, 

    _setOption: function(key, value) { 
     var previousValue = this.options[key]; 
     if(previousValue == value) return; 

     this.options[key] = value; 

     switch(key) { 
      case "id": 
       this.element.attr({id: this.options.id}); 
       this.refreshTabs(); 
       break; 
     } 
    }, 

    /** 
    Invoke refresh on the parent tab to let it know that something has changed. 
    This also preserves the active index by setting it back to what it was before the refresh, which 
    may correspond to a different tab after the refresh. 
    */ 
    refreshTabs: function() { 
     var previousActiveIndex = this.tabsElement.tabs("option", "active"); 
     this.tabsElement.tabs("refresh"); 
     this.tabsElement.tabs("option", "active", previousActiveIndex);   
    } 
});