2013-05-11 14 views
14

Sto cercando di tenere traccia della scheda selezionata nel modello di visualizzazione ma non riesco a farlo funzionare.Tieni traccia delle schede con knockoutjs + twitter bootstrap

Nel seguente codice quando si fa clic su una scheda, l'intestazione si aggiorna correttamente ma il contenuto della scheda non viene visualizzato. Se si rimuove , click: $parent.selectSection, i contenuti vengono visualizzati ma l'intestazione non viene aggiornata.

Ora se si rimuove il data-bind="css: { active: selected }" da li allora sembra funzionare quando si fa clic sulle schede ma il pulsante per selezionare la seconda scheda non lo fa.

Come posso fare questo lavoro?

See: http://jsfiddle.net/5PgE2/3/

HTML:

<h3> 
    <span>Selected: </span> 
    <span data-bind="text: selectedSection().name" /> 
</h3> 
<div class="tabbable"> 
    <ul class="nav nav-tabs" data-bind="foreach: sections"> 
     <li data-bind="css: { active: selected }"> 
      <a data-bind="attr: { href: '#tab' + name } 
, click: $parent.selectSection" data-toggle="tab"> 
       <span data-bind="text: name" /> 
      </a> 
     </li> 
    </ul> 
    <div class="tab-content" data-bind="foreach: sections"> 
     <div class="tab-pane" data-bind="attr: { id: 'tab' + name }"> 
      <span data-bind="text: 'In section: ' + name" /> 
     </div> 
    </div> 
</div> 
<button data-bind="click: selectTwo">Select tab Two</button> 

JS:

var Section = function (name) { 
    this.name = name; 
    this.selected = ko.observable(false); 
} 

var ViewModel = function() { 
    var self = this; 
    self.sections = ko.observableArray([new Section('One'), 
    new Section('Two'), 
    new Section('Three')]); 
    self.selectedSection = ko.observable(new Section('')); 
    self.selectSection = function (s) { 
     self.selectedSection().selected(false); 

     self.selectedSection(s); 
     self.selectedSection().selected(true); 
    } 

    self.selectTwo = function() { self.selectSection(self.sections()[1]); } 
} 

ko.applyBindings(new ViewModel()); 

risposta

30

Ci sono diversi modi che è possibile gestire JS questo sia utilizzando del bootstrap o semplicemente avere Knockout Aggiungi/Rimuovi la classe active.

Per fare ciò con Knockout, ecco una soluzione in cui la Sezione stessa ha calcolato per determinare se è attualmente selezionata.

var Section = function (name, selected) { 
    this.name = name; 
    this.isSelected = ko.computed(function() { 
     return this === selected(); 
    }, this); 
} 

var ViewModel = function() { 
    var self = this; 

    self.selectedSection = ko.observable(); 

    self.sections = ko.observableArray([ 
     new Section('One', self.selectedSection), 
     new Section('Two', self.selectedSection), 
     new Section('Three', self.selectedSection) 
    ]); 

    //inialize to the first section 
    self.selectedSection(self.sections()[0]); 
} 

ko.applyBindings(new ViewModel()); 

Markup sarebbe simile:

<div class="tabbable"> 
    <ul class="nav nav-tabs" data-bind="foreach: sections"> 
     <li data-bind="css: { active: isSelected }"> 
      <a href="#" data-bind="click: $parent.selectedSection"> 
       <span data-bind="text: name" /> 
      </a> 
     </li> 
    </ul> 
    <div class="tab-content" data-bind="foreach: sections"> 
     <div class="tab-pane" data-bind="css: { active: isSelected }"> 
      <span data-bind="text: 'In section: ' + name" /> 
     </div> 
    </div> 
</div> 

campione qui: http://jsfiddle.net/rniemeyer/cGMTV/

Ci sono una serie di varianti che si potrebbe usare, ma penso che questo sia un approccio semplice.

Ecco un tweak in cui la scheda attiva ha utilizzato il nome della sezione come modello: http://jsfiddle.net/rniemeyer/wbtvM/

Problemi correlati