我在项目中使用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
答案 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显示模态。