Probably the best option in the long run is to convert these bootstrap widgets into custom knockout bindings (e.g. https://github.com/billpull/knockout-bootstrap ) or even better into Durandal widgets.
See how MessageBox Durandal 1.2 is implemented. This can be used as a rough guide for converting bootstrap tabs and drop-down lists to Durandal widgets. As you can see, the href attributes in the view have been replaced with data-bind="click: ..." . In addition, you will have to convert the JavaScript Bootstrap to a Durandal viewmodel .
eg. http://twitter.imtqy.com/bootstrap/javascript.html#modals
<div class="modal hide fade"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h3>Modal header</h3> </div> <div class="modal-body"> <p>One fine bodyβ¦</p> </div> <div class="modal-footer"> <a href="#" class="btn">Close</a> <a href="#" class="btn btn-primary">Save changes</a> </div> </div>
becomes
https://github.com/dFiddle/dFiddle-1.2/blob/gh-pages/App/durandal/messageBox.html
<div class="messageBox"> <div class="modal-header"> <h3 data-bind="html: title"></h3> </div> <div class="modal-body"> <p class="message" data-bind="html: message"></p> </div> <div class="modal-footer" data-bind="foreach: options"> <button class="btn" data-bind="click: function () { $parent.selectOption($data); }, html: $data, css: { 'btn-primary': $index() == 0, autofocus: $index() == 0 }"></button> </div> </div>
Update: The minimal implementation of the tab widget is performed here. Live version at http://dfiddle.imtqy.com/dFiddle-2.0/#bootstrap
View:
<div class="tabs"> <ul class="nav nav-tabs" data-bind="foreach: { data: settings.items }"> <li data-bind="css: {active: isActive}"> <a data-bind="text: name, click: $parent.toggle.bind($parent)"></a> </li> </ul> <div class="tab-content" data-bind="foreach: { data: settings.items}"> <div class="tab-pane" data-bind="html: content, css: {active: isActive}"></div> </div> </div>
viewmodel:
define(['durandal/composition', 'jquery'], function(composition, $) { var ctor = function() { }; ctor.prototype.activate = function(settings) { this.settings = settings; }; ctor.prototype.detached = function() { console.log('bootstrap/widget/viewmodel: detached', arguments, this); }; ctor.prototype.toggle = function(model, event){ this.deactivateAll(); model.isActive(true); }; ctor.prototype.deactivateAll = function(){ $.each(this.settings.items(), function(idx, tab){ tab.isActive(false); }); }; return ctor; });