2011-09-11 54 views
6

我一直在嘗試使用淘汰賽添加/刪除jQueryUI選項卡,但沒有任何運氣。 我的視圖模型是一個Effect對象的數組。我想從選項卡控件中添加/刪除一個選項卡,因爲對象是從視圖模型中添加/刪除的。如何使用knockout JS添加或刪除jQueryUI選項卡?

這裏有一個的jsfiddle有人開始和我更新這說明什麼,我希望做 JSFiddle example

當您嘗試添加一個標籤,因爲它會打破。我想我需要將模板綁定與新的自定義綁定結合起來,以便銷燬/重新創建我認爲的選項卡控件。我非常感謝任何幫助。謝謝!

回答

0

每當模型更改時,您很可能不得不重新渲染選項卡界面。

此外,添加一個唯一的ID標籤<ul>

<ul id="tabs"> 

每次模式的轉變,叫

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

(我不確定如何斷火與淘汰賽,但我的事件確定它在文檔中。)

0

我有一個非常類似的問題。我有一個深層視圖模型圖,其中頂級可觀察子視圖模型數組被表示爲選項卡,並且每個選項卡呈現孫標記數據的標記。最初我使用jQuery UI選項卡在Knockout構建它後封鎖我的標記。

我有添加,刪除和複製這些標籤式視圖模型/域對象的功能。有了jQuery UI選項卡,我最終必須調用destroy並重建它,對於重複的情況,我必須首先存儲選定的索引,然後在重新創建後選擇index + 1,以選擇新創建的選項卡。

但是現在我已經更加完全地接受MVVM作爲我的UI的驅動程序,並且完全剔除了jQuery選項卡並將我自己的選項卡標題和選項卡內容元素綁定到我的Knockout視圖模型上的「isSelected」可觀察屬性。我發現這樣更乾淨,給我更多的靈活性,標籤的標籤/ CSS變得簡單而優雅。

那isSelected屬性也意味着我可以通過爲每個選項卡指定類似<div class="child" data-bind="if: isSelected">來提高綁定效率。以前(推測)Knockout是不必要的通過不可見標籤的所有綁定工作。

這就是我現在通常想要接近我的用戶界面 - 儘可能避免使用直接過程用戶界面的東西來支持使用綁定。

3

我想我會用一個新的解決方案更新這個問題,我開始使用。我以前一直使用RP Niemeyer的小提琴http://jsfiddle.net/rniemeyer/dsKbH/作爲動態添加/刪除綁定到KO observableArray的jQuery UI選項卡的基礎。

在過去的幾個月裏,我碰到了與我的應用相關的一些問題:A)setTimeout()推遲,B)每次觸發更新時銷燬和重新創建選項卡小部件。所以我想出了一個不同的方法來避免這些問題,恕我直言,這是一種更優雅的技術。

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

的核心思想是介紹一個非常簡單的自定義綁定名爲「一個tabpanel」和相應的部件,綁定到你的標籤面板內容的div。由於KO基於您的observableArray創建和刪除這些div,tabPanel綁定會確保使用它的「刷新」方法更新jQueryUI.tabs。我認爲這比試圖讓標籤在容器元素的綁定中更新(並在適當的時候)更順暢。從小提琴

相關代碼

/** 
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);   
    } 
}); 
相關問題