2011-09-11 11 views
6

Ho cercato di usare il knockout per aggiungere/rimuovere le schede jQueryUI ma non ho avuto fortuna. Il mio modello di vista è un array di oggetti Effect. Vorrei aggiungere/rimuovere una scheda dal controllo struttura a schede quando gli oggetti vengono aggiunti/rimossi dal modello di visualizzazione.Come aggiungere o rimuovere le schede jQueryUI usando il knockout JS?

Ecco un JSFiddle qualcuno ha iniziato e ho aggiornato che mostra quello che sto cercando di fare JSFiddle example

Si romperà quando si tenta di aggiungere una scheda. Penso che ho bisogno di combinare il modello di associazione w/un nuovo legame personalizzato che può distruggere/ricreare il controllo tabulazione credo. Apprezzerei molto ogni aiuto. Grazie!

risposta

0

Molto probabilmente sarà necessario rieseguire il rendering dell'interfaccia delle schede ogni volta che il modello cambia.

Inoltre, aggiungere un ID unico per le schede <ul>:

<ul id="tabs"> 

Ogni volta che il modello cambia, chiamano

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

(io sono sicuri di come sparare un evento con Knockout ma io sono sicuro che sia nella documentazione.)

0

Ho avuto un problema molto simile. Ho un grafico del modello di una vista profonda in cui la matrice osservabile di primo livello dei modelli di vista figlio è rappresentata come schede, e ogni scheda rende markup per i dati di grandchild. Originariamente stavo usando le schede dell'interfaccia utente di jQuery per tabificare il mio markup dopo che Knockout lo aveva creato.

Ho la funzionalità per aggiungere, rimuovere e duplicare quei modelli di visualizzazione a schede/oggetti di dominio. Con le schede dell'interfaccia utente jQuery ho finito per dover chiamare distruggere su di esso e poi ricostruirlo, e per casi come Duplicato ho dovuto prima memorizzare l'indice selezionato e poi selezionare quell'indice + 1 dopo la ricreazione, per selezionare la scheda appena creata.

Ma ora sono arrivato ad abbracciare MVVM come driver dell'interfaccia utente e ho abbattuto le schede jQuery e ho associato le intestazioni delle schede e gli elementi di contenuto della scheda a una proprietà osservabile "isSelected" sui miei modelli di visualizzazione Knockout . Ho trovato questo molto più pulito e mi dà modo più flessibilità, e il markup/CSS per le schede si è rivelato semplice ed elegante.

Ciò significa che è possibile aumentare l'efficienza di associazione specificando qualcosa come <div class="child" data-bind="if: isSelected"> per ogni scheda. Precedentemente (presumibilmente) Knockout stava funzionando inutilmente attraverso tutti i collegamenti delle schede invisibili.

Questo è il modo in cui sto tentando di avvicinarmi alla mia interfaccia utente in generale ora, evitando il più possibile l'interfaccia utente procedurale diretta a favore dell'utilizzo dei collegamenti.

3

Ho pensato di aggiornare questa domanda con una nuova versione di una soluzione che ho iniziato a utilizzare. In precedenza avevo utilizzato il violino di RP Niemeyer http://jsfiddle.net/rniemeyer/dsKbH/ come base per l'aggiunta/rimozione dinamica di schede dell'interfaccia utente jQuery legate a un ObservableArray KO.

Negli ultimi mesi mi sono imbattuto in alcuni problemi nella mia app relativi a A) Il differimento setTimeout() e B) Il distruggere e ricreare il widget schede ogni volta che viene attivato un aggiornamento. Così ho trovato un approccio diverso che evita questi problemi, e IMHO, è una tecnica più elegante.

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

L'idea chiave è quella di introdurre una semplice associazione personalizzata chiamata "tabpanel" e un corrispondente widget che si associa alla scheda div contenuti del pannello. Poiché KO crea e rimuove questi div in base al tuo osservableArray, il binding tabPanel si assicura di aggiornare jQueryUI.tabs usando il suo metodo "refresh". Questo funziona molto più agevolmente penso che cercare di far aggiornare le schede (e al momento giusto) nelle associazioni degli elementi del contenitore.

relativo codice da violino

/** 
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);   
    } 
}); 
Problemi correlati