2013-05-11 7 views
14

Ich versuche, die ausgewählte Registerkarte im Ansichtsmodell zu verfolgen, aber ich kann nicht scheinen, damit es funktioniert.Registerkarten mit knockoutjs + twitter Bootstrap behalten

Im folgenden Code, wenn Sie auf eine Registerkarte klicken, wird die Kopfzeile korrekt aktualisiert, aber der Inhalt der Registerkarte wird nicht angezeigt. Wenn Sie , click: $parent.selectSection entfernen, wird der Inhalt angezeigt, aber die Kopfzeile wird nicht aktualisiert.

Jetzt, wenn Sie die aus der li entfernen, dann scheint es zu funktionieren, wenn Sie auf die Registerkarten klicken, aber die Schaltfläche zum Auswählen der zweiten Registerkarte nicht.

Wie kann ich das schaffen?

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()); 

Antwort

30

Es gibt mehrere Möglichkeiten, wie Sie dies entweder JS die mit Bootstrap verarbeiten kann oder nur mit Knockout hinzufügen/entfernen die active Klasse.

Um dies nur mit Knockout zu tun, hier ist eine Lösung, wo der Abschnitt selbst berechnet hat, um festzustellen, ob es gerade ausgewählt ist.

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 würde wie folgt aussehen:

<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> 

Beispiel hier: http://jsfiddle.net/rniemeyer/cGMTV/

Es gibt eine Reihe von Variationen, die Sie nutzen könnten, aber ich denke, dass dies ein einfacher Ansatz ist.

Hier ist eine Optimierung, wo die aktive Registerkarte den Abschnitt Name als Vorlage verwendet: http://jsfiddle.net/rniemeyer/wbtvM/

Verwandte Themen