【问题标题】:Modal from inside Bootstrap Tabs using Knockout foreach使用 Knockout foreach 的 Bootstrap 选项卡内部的模态
【发布时间】:2015-09-08 05:45:00
【问题描述】:

我使用 foreach 绑定将 Bootstrap 选项卡绑定到 KnockoutJS 可观察数组,这工作正常。我现在想从活动选项卡内启动一个引导模式。

<div class="tab-content">
    <!-- ko foreach: trueData -->       
    <div class="tab-pane fade in" data-bind="css:{active: $index() == 0}, attr :{'id': 'tab' + $index()}">
    </div>
</div>

为此,Bootstrap 模式代码必须放在 TABS divs 内,但这是针对 this "Modal markup placement" rule

当我这样做时,只会打开第一个选项卡内的模式。其他选项卡中的模态不打开。

解决方法是什么? 有没有办法获取活动选项卡的索引并做一个单独的foreach 并根据它过滤绑定剔除数组?

【问题讨论】:

    标签: jquery twitter-bootstrap knockout.js twitter-bootstrap-3


    【解决方案1】:

    我建议为此使用完全不同的模式。

    $root 视图模型级别使用一个引导模式。此模式显示根视图模型 observable currentModalItem 的数据,并在该 observable 为 null 时隐藏。通过从选项卡内部设置可观察的模式来激活模式。

    这确实需要自定义模式绑定,但创建或修改并不难。我的示例使用the custom binding from another answer by @huocp,但您可以根据需要进行更改。

    以某种方式创建选项卡也很有用,下面的示例使用基于this answer by @RPNiemeyer 的版本。

    这是一个例子:

    ko.bindingHandlers.modal = {
        init: function (element, valueAccessor) {
            $(element).modal({
                show: false
            });
    
            var value = valueAccessor();
            if (ko.isObservable(value)) {
                $(element).on('hide.bs.modal', function() {
                   value(false);
                });
            }
            ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
               $(element).modal("destroy");
            });
    
        },
        update: function (element, valueAccessor) {
            var value = valueAccessor();
            if (ko.utils.unwrapObservable(value)) {
                $(element).modal('show');
            } else {
                $(element).modal('hide');
            }
        }
    }
    
    var ItemViewModel = function(data, initiallySelected) {
      this.isSelected = ko.observable(!!initiallySelected);
      this.txt = ko.observable(data);
    };
    
    var RootViewModel = function() {
      var self = this;
      
      self.currentModalItem = ko.observable(null);
      
      self.items = ko.observableArray([new ItemViewModel("Apples", true), new ItemViewModel("Oranges"), new ItemViewModel("Pears")]);
      
      self.selectItem = function(item) {
        self.items().forEach(function(i) { i.isSelected(false); });
        item.isSelected(true);
      };
      
      self.openModal = function(item) {
        self.currentModalItem(item);
      };
    };
    
    ko.applyBindings(new RootViewModel());
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <div class="modal fade" data-bind="modal: !!currentModalItem(), with: currentModalItem">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-body">
            <p>You opened item: <i data-bind="text: txt"></i></p>
          </div>
        </div>
      </div>
    </div>
    
    <div>
      <!-- Nav tabs -->
      <ul class="nav nav-tabs" data-bind="foreach: items">
        <li data-bind="css: { active: isSelected }">
          <a href="#" data-bind="text: txt, click: $parent.selectItem"></a>
        </li>
      </ul>
    
      <!-- Tab panes -->
      <div class="tab-content" data-bind="foreach: items">
        <div class="tab-pane" data-bind="css: { active: isSelected }">
          <h3 data-bind="text: txt"></h3>
          <p><a href="#" data-bind="click: $root.openModal">Open Modal!</a></p>
        </div>
      </div>
    </div>

    的确,它还不完美(目前),但以上内容应该可以帮助您入门。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-07
      • 2015-08-28
      • 2021-12-25
      • 1970-01-01
      • 2012-09-07
      • 2019-10-20
      • 1970-01-01
      相关资源
      最近更新 更多