나는이 질문을 내가 사용하기 시작한 새로운 해결책으로 업데이트 할 것이라고 생각했다. 나는 이전에 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를 업데이트합니다. 이 작업은 컨테이너 요소의 바인딩에서 (그리고 적시에) 업데이트 할 탭을 얻는 것보다 훨씬 부드럽게 작동합니다. 바이올린에서
관련 코드
/**
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);
}
});