使用bootstrap和knockout.js显示选项卡

时间:2015-05-15 05:59:36

标签: javascript twitter-bootstrap knockout.js

我正在尝试使用Bootstrap显示标签。

使用此代码标签不会出现。

查看:

<div id="tabs" class="container">
  <ul class="nav nav-tabs">
    <ul class="folders" data-bind="foreach: folders">
      <li data-bind="text: $data, css:{ selected: $data == $root.chosenFolderId() }, click: $root.goToFolder" >
        <a href="#home" data-toggle="tab"></a>
        <a href="#home" data-toggle="tab">
      </li>
    </ul>
  < /ul>
</div>

查看型号:

function WebmailViewModel() {
    // Data
    var self = this;
    self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
    self.chosenFolderId = ko.observable();

    // Behaviours    
    self.goToFolder = function(folder) { self.chosenFolderId(folder); };    
};

ko.applyBindings(new WebmailViewModel());

我的代码有什么问题?

2 个答案:

答案 0 :(得分:2)

您已发布的代码中存在很多的问题:

  • 您发布的标记无效:有一个未关闭的迷路a标记。
  • 您发布的标记无效:ul是第一个ul的直接后代,您可能只需要一个。
  • 为什么在一个标签a中会有两个 li个标签?你只想要一个。
  • 您同时拥有litext绑定的内容(将覆盖内容)。 Bootstrap需要a,因此您应该将绑定移动到我认为的那个元素。
  • click绑定应该在a标记上,而不是li
  • 您为有效的selected项呈现li课程,但如果您查看the Bootstrap documentation,则会发现它应该是active
  • 您将Bootstrap中的data-*属性(即data-toggle)与选择制表符(clickcss绑定)的Knockout方式混合在一起。你可能只想要后者

在解决了所有这些问题之后(可能还有一两件我上面忘记提到的小事),你最终得到了以下内容:

&#13;
&#13;
function WebmailViewModel() {
    // Data
    var self = this;
    self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
    self.chosenFolderId = ko.observable();

    // Behaviours    
    self.goToFolder = function(folder) { self.chosenFolderId(folder); };    
};

ko.applyBindings(new WebmailViewModel());
&#13;
body { padding: 10px; }
&#13;
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div id="tabs" class="container">
  <ul class="nav nav-tabs folders" data-bind="foreach: folders">
      <li data-bind="css:{ active: $data == $root.chosenFolderId() }">
        <a href="#" data-bind="text: $data, click: $root.goToFolder"></a>
      </li>
  </ul>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

在纠正了Jeroen所指出的所有错误之后,还有一点改进:

function WebmailViewModel() {
    var self = this;
    self.folders = [
        {id: '#inbox', name: 'Inbox'}, 
        {id: '#archive', name: 'Archive'}, 
        {id: '#sent', name: 'Sent'}, 
        {id: '#spam', name: 'Spam'}
    ];
    self.chosenFolder = ko.observable(self.folders[0]);
}

$(function () {
    ko.applyBindings(new WebmailViewModel());
});
<link href="http://getbootstrap.com/dist/css/bootstrap.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.0/bootstrap.min.js"></script>


<div id="tabs" class="container">
    <ul class="nav nav-tabs" role="tablist" data-bind="foreach: folders">
        <li data-bind="
            click: $root.chosenFolder, 
            css: { active: $data === $root.chosenFolder() }
        ">
            <a href="" role="tab" data-toggle="tab" data-bind="
                text: name, attr: {href: id}
            "></a>
        </li>
    </ul>
    <div>Tab content here</div>
</div>

请注意,observable本身就是函数。如果要将单击的对象存储在observable中,可以直接将该observable指定为单击处理程序。

当发生click事件时,knockout将调用事件处理程序并将被点击的对象作为第一个参数传递,这很方便地就是你在knockout中设置observable值的方式。