Knockout w / Bootstrap Modals - Modal出现两次

时间:2014-08-06 16:24:46

标签: javascript twitter-bootstrap knockout.js

我在项目中使用Knockout.js和Bootstrap。我希望能够显示一个链接/按钮,为我的收藏中的该项目打开一个模态。当点击链接/按钮打开集合中某个项目的模态时,我的自定义绑定的update事件被多次触发,我不知道为什么会这样,我也不确定如何停止它多次射击。我怎么能做到这一点?

    // JavaScript custom binding and model
    ko.bindingHandlers.showModal = {
    init: function (element, valueAccessor) {
        $(element).modal({
            show: false
        });

        var value = valueAccessor();

        if (typeof value === 'function') {
            $(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 viewModel = {
  displayModal: ko.observable(false),
  kids: ['Jack', 'Jill']
};

ko.applyBindings(viewModel);

<script type="text/html" id="child-header-template">
<h3 data-bind='text:$data'></h3>
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal" data-bind="click: function () { $root.displayModal(true); }, showModal:  $root.displayModal">
Launch demo modal
</button>
<div class="modal fade" id="myModal" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        <span>Filler</span>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
</script>

<div data-bind='foreach: kids'>
<!-- ko template: { name: 'child-header-template' } -->
<!-- /ko -->
</div>

可以查看Jsbin版本here

1 个答案:

答案 0 :(得分:2)

问题是您正在使用相同的ID(#myModal)将多个模态注入到页面中。这使得Bootstrap模态数据API(http://getbootstrap.com/javascript/#js-data-attrs)混乱并导致它产生多个模态。

这是一个简化的解决方案(http://jsbin.com/linopelu/2/edit):

<html>
<head>
  <script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
  <script src="//code.jquery.com/jquery.min.js"></script>
  <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
  <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
  <script>
$(window.document).ready(function () {
    var viewModel = function () {
      var self = this;

      this.displayModal = ko.observable(false);
      this.kids = ['Jack', 'Jill'];
      this.selectedKid = ko.observable();
      this.buttonClick = function () {
        self.selectedKid(this);
      };
    };

    ko.applyBindings(new viewModel());
});
  </script>
</head>
<body>
  <h2>Hello there</h2>
  <!-- ko foreach: kids -->
  <h3 data-bind='text:$data'></h3>
  <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal" data-bind="click: $parent.buttonClick">
  Launch demo modal
  </button>
  <!-- /ko -->

  <div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog">
      <div data-bind="with: selectedKid" class="modal-content">
        <div class="modal-header">
          <h4 data-bind="text: $data" class="modal-title" id="myModalLabel"></h4>
        </div>
        <div class="modal-body">
          <span>Filler</span>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

此解决方案只有一个模态绑定到视图模型上的selectedKid observable。单击该按钮时,将更新此可观察值,并通过引导数据API显示模态。