使用 Bootstrap 模态的 Knockout JS
Knockout JS with Bootstrap Modal
我有一个简单的页面,其中有一个按钮可以触发模式打开。我的所有代码都在这个 JSFiddle 中:
下面还有:
$('#displayDetails').click(() => {
let obj = {
Overview: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
Mileage: 36,
From: " Location 1",
To: "Location 2",
Districts: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
}
ko.cleanNode(document.getElementById("tabPanel1"));
ko.applyBindings(obj, document.getElementById("tabPanel1"))
$('#modalOverlay').modal('show');
})
.modal.modal-fullscreen .modal-dialog {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
max-width: none;
z-index: 3000;
}
.modal.modal-fullscreen .modal-content {
height: auto;
height: 100vh;
border-radius: 0;
border: none;
}
.modal.modal-fullscreen .modal-body {
overflow-y: auto;
}
<!--
Bootstrap docs: https://getbootstrap.com/docs
-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<button id="displayDetails">Click to see modal</button>
<div class="modal fade modal-fullscreen" id="modalOverlay" tabindex="-1" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 id="modal_header"></h1>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<section id="tabs" class="project-tab">
<!-- <div class="container"> -->
<div class="row">
<div class="col-md-12">
<nav>
<div class="nav nav-tabs nav-fill" id="nav-tab" role="tablist">
<a class="nav-item nav-link active" id="nav-1-tab" data-toggle="tab"
href="#nav-1" role="tab" aria-controls="nav-1"
aria-selected="true">Tab 1</a>
<a class="nav-item nav-link" id="nav-2-tab" data-toggle="tab"
href="#nav-2" role="tab" aria-controls="nav-2"
aria-selected="false">Tab 2</a>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade" id="nav-1" role="tabpanel"
aria-labelledby="nav-1-tab">
<div id="tabPanel1" class="details-tab-pane tab-pane in active" role="tabpanel"
aria-label="Overview">
<div class="container">
<div class="details-content__wrapper">
<div class="row">
<div class="col-md-6 details-content">
<p data-bind="text: Overview"></p>
<p>Mileage & Terminus <span data-bind="text: Mileage" data-format="n1"></span>
miles from
<span data-bind="text: From"></span> to
<span data-bind="text: To"></span>
</p>
<p>Highway District(s)
<span data-bind="text: Districts"></span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-2" role="tabpanel"
aria-labelledby="nav-2-tab">
<h3>This is Tab 2</h3>
</div>
</div>
</div>
</div>
<!-- </div> -->
</section>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.js"></script>
我在模式中有 2 个选项卡。第一个选项卡包含一些带有可变文本的内容。我正在使用 Knockout JS 来填写内容中的可变文本。但是,我第一次单击按钮打开模式时,Tab 1 是空白的,我必须切换到 Tab 2 并返回 Tab 1 才能显示 Tab 1 的内容。我是 Knockout JS 的新手,不知道我做错了什么。感谢您的帮助!
I'm a rookie with Knockout JS and don't know what I am doing wrong.
我认为您的问题不在于 Knockout,而在于 Bootstrap 选项卡。如果您查看每个选项卡上的 CSS 类,当您单击其中一个选项卡时,您会看到 active show
添加到 类;当您第一次显示模式(带有选项卡)时,这些 类 尚未添加到 Tab 1 因此 Bootstrap JS 不知道您想要它显示。
目前您的选项卡设置为在点击时显示,这就是为什么点击 Tab 2 然后 然后 点击 Tab 1 使其显示。
可能有一种方法可以使用 Bootstrap 标签 JavaScript 来解决这个问题,但是当你用 knockoutjs
标记它时,你可以强制 Tab 1 通过自己添加 CSS 类 来显示 - 使用 Knockout observable 或 vanilla JS。
ko.bindingHandlers.modal = {
init: function (element, valueAccessor) {
this.Overview = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
this.Mileage= 'Test';
this.From = 'Test';
this.To = 'Test';
this.Districts = 'Test';
$(element).modal({
show: false
});
var value = valueAccessor();
if (ko.isObservable(value)) {
$(element).on('hidden.bs.modal', function() {
value(false);
});
}
},
update: function (element, valueAccessor) {
var value = valueAccessor();
if (ko.utils.unwrapObservable(value)) {
$(element).modal('show');
} else {
$(element).modal('hide');
}
}
}
function PopupViewModel() {
var self = this;
this.showDialog = ko.observable(false);
this.submit = function () {
alert('submit');
self.showDialog(false);
}
}
ko.applyBindings(new PopupViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet"/>
<div class="modal fade" tabindex="-1" role="dialog" data-bind="modal:showDialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body">
<section id="tabs" class="project-tab">
<!-- <div class="container"> -->
<div class="row">
<div class="col-md-12">
<nav>
<div class="nav nav-tabs nav-fill" id="nav-tab" role="tablist">
<a class="nav-item nav-link" id="nav-1-tab" data-toggle="tab" href="#nav-1" role="tab" aria-controls="nav-1" aria-selected="true">Tab 1</a>
<a class="nav-item nav-link" id="nav-2-tab" data-toggle="tab" href="#nav-2" role="tab" aria-controls="nav-2" aria-selected="false">Tab 2</a>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade" id="nav-1" role="tabpanel" aria-labelledby="nav-1-tab">
<div id="tabPanel1" class="details-tab-pane tab-pane in" role="tabpanel" aria-label="Overview">
<div class="container">
<div class="details-content__wrapper">
<div class="row">
<div class="col-md-6 details-content">
<p data-bind="text: Overview"></p>
<p>Mileage & Terminus <span data-bind="text: Mileage" data-format="n1"></span>
miles from
<span data-bind="text: From"></span> to
<span data-bind="text: To"></span>
</p>
<p>Highway District(s)
<span data-bind="text: Districts"></span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-2" role="tabpanel" aria-labelledby="nav-2-tab">
<h3>This is Tab 2</h3>
</div>
</div>
</div>
</div>
<!-- </div> -->
</section>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-xs" data-bind="click : submit">Close</button>
</div>
</div>
</div>
</div>
<button data-bind="click: function(){showDialog(true)}">Show</button>
不完美,但也许它会帮助你更进一步。
我有一个简单的页面,其中有一个按钮可以触发模式打开。我的所有代码都在这个 JSFiddle 中:
下面还有:
$('#displayDetails').click(() => {
let obj = {
Overview: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
Mileage: 36,
From: " Location 1",
To: "Location 2",
Districts: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
}
ko.cleanNode(document.getElementById("tabPanel1"));
ko.applyBindings(obj, document.getElementById("tabPanel1"))
$('#modalOverlay').modal('show');
})
.modal.modal-fullscreen .modal-dialog {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
max-width: none;
z-index: 3000;
}
.modal.modal-fullscreen .modal-content {
height: auto;
height: 100vh;
border-radius: 0;
border: none;
}
.modal.modal-fullscreen .modal-body {
overflow-y: auto;
}
<!--
Bootstrap docs: https://getbootstrap.com/docs
-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<button id="displayDetails">Click to see modal</button>
<div class="modal fade modal-fullscreen" id="modalOverlay" tabindex="-1" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 id="modal_header"></h1>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<section id="tabs" class="project-tab">
<!-- <div class="container"> -->
<div class="row">
<div class="col-md-12">
<nav>
<div class="nav nav-tabs nav-fill" id="nav-tab" role="tablist">
<a class="nav-item nav-link active" id="nav-1-tab" data-toggle="tab"
href="#nav-1" role="tab" aria-controls="nav-1"
aria-selected="true">Tab 1</a>
<a class="nav-item nav-link" id="nav-2-tab" data-toggle="tab"
href="#nav-2" role="tab" aria-controls="nav-2"
aria-selected="false">Tab 2</a>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade" id="nav-1" role="tabpanel"
aria-labelledby="nav-1-tab">
<div id="tabPanel1" class="details-tab-pane tab-pane in active" role="tabpanel"
aria-label="Overview">
<div class="container">
<div class="details-content__wrapper">
<div class="row">
<div class="col-md-6 details-content">
<p data-bind="text: Overview"></p>
<p>Mileage & Terminus <span data-bind="text: Mileage" data-format="n1"></span>
miles from
<span data-bind="text: From"></span> to
<span data-bind="text: To"></span>
</p>
<p>Highway District(s)
<span data-bind="text: Districts"></span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-2" role="tabpanel"
aria-labelledby="nav-2-tab">
<h3>This is Tab 2</h3>
</div>
</div>
</div>
</div>
<!-- </div> -->
</section>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.js"></script>
I'm a rookie with Knockout JS and don't know what I am doing wrong.
我认为您的问题不在于 Knockout,而在于 Bootstrap 选项卡。如果您查看每个选项卡上的 CSS 类,当您单击其中一个选项卡时,您会看到 active show
添加到 类;当您第一次显示模式(带有选项卡)时,这些 类 尚未添加到 Tab 1 因此 Bootstrap JS 不知道您想要它显示。
目前您的选项卡设置为在点击时显示,这就是为什么点击 Tab 2 然后 然后 点击 Tab 1 使其显示。
可能有一种方法可以使用 Bootstrap 标签 JavaScript 来解决这个问题,但是当你用 knockoutjs
标记它时,你可以强制 Tab 1 通过自己添加 CSS 类 来显示 - 使用 Knockout observable 或 vanilla JS。
ko.bindingHandlers.modal = {
init: function (element, valueAccessor) {
this.Overview = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
this.Mileage= 'Test';
this.From = 'Test';
this.To = 'Test';
this.Districts = 'Test';
$(element).modal({
show: false
});
var value = valueAccessor();
if (ko.isObservable(value)) {
$(element).on('hidden.bs.modal', function() {
value(false);
});
}
},
update: function (element, valueAccessor) {
var value = valueAccessor();
if (ko.utils.unwrapObservable(value)) {
$(element).modal('show');
} else {
$(element).modal('hide');
}
}
}
function PopupViewModel() {
var self = this;
this.showDialog = ko.observable(false);
this.submit = function () {
alert('submit');
self.showDialog(false);
}
}
ko.applyBindings(new PopupViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet"/>
<div class="modal fade" tabindex="-1" role="dialog" data-bind="modal:showDialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body">
<section id="tabs" class="project-tab">
<!-- <div class="container"> -->
<div class="row">
<div class="col-md-12">
<nav>
<div class="nav nav-tabs nav-fill" id="nav-tab" role="tablist">
<a class="nav-item nav-link" id="nav-1-tab" data-toggle="tab" href="#nav-1" role="tab" aria-controls="nav-1" aria-selected="true">Tab 1</a>
<a class="nav-item nav-link" id="nav-2-tab" data-toggle="tab" href="#nav-2" role="tab" aria-controls="nav-2" aria-selected="false">Tab 2</a>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade" id="nav-1" role="tabpanel" aria-labelledby="nav-1-tab">
<div id="tabPanel1" class="details-tab-pane tab-pane in" role="tabpanel" aria-label="Overview">
<div class="container">
<div class="details-content__wrapper">
<div class="row">
<div class="col-md-6 details-content">
<p data-bind="text: Overview"></p>
<p>Mileage & Terminus <span data-bind="text: Mileage" data-format="n1"></span>
miles from
<span data-bind="text: From"></span> to
<span data-bind="text: To"></span>
</p>
<p>Highway District(s)
<span data-bind="text: Districts"></span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-2" role="tabpanel" aria-labelledby="nav-2-tab">
<h3>This is Tab 2</h3>
</div>
</div>
</div>
</div>
<!-- </div> -->
</section>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-xs" data-bind="click : submit">Close</button>
</div>
</div>
</div>
</div>
<button data-bind="click: function(){showDialog(true)}">Show</button>
不完美,但也许它会帮助你更进一步。