मैंने सोचा कि मैं इस प्रश्न को एक समाधान पर एक नए टेक के साथ अपडेट कर दूंगा जिसका उपयोग मैंने शुरू किया था। मैं पहले आरओ निमेयर के फीड http://jsfiddle.net/rniemeyer/dsKbH/ का उपयोग कर रहा था क्योंकि केओ अवलोकन योग्य ऐरे से जुड़े jQuery UI टैब को गतिशील रूप से जोड़/हटाया जा रहा था।
पिछले कुछ महीनों में मैंने ए से संबंधित मेरे ऐप में कुछ समस्याओं के खिलाफ उछाल दिया है) सेटटाइमआउट() स्थगित, और बी) हर बार अपडेट ट्रिगर होने पर टैब विजेट का विनाश और पुन: निर्माण। तो मैं एक अलग दृष्टिकोण के साथ आया जो इन मुद्दों से बचाता है, और आईएमएचओ, एक और अधिक सुरुचिपूर्ण तकनीक है।
http://jsfiddle.net/LatencyMachine/XJPJZ/
कुंजी विचार एक बहुत ही सरल कस्टम "tabPanel" कहा जाता है बंधन और एक इसी विजेट है कि आप अपने टैब पैनल सामग्री divs करने के लिए बाध्य शुरू करने की है। चूंकि केओ आपके पर्यवेक्षण के आधार पर इन divs को बनाता है और हटा देता है, टैबपैन बाध्यकारी 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);
}
});