Knockout JS:如何使用"with"或clear Node来处理knockout js的Multiple bindings error?
Knockout JS: How should "with" or clearnNode be used to deal with Multiplle bindings error with knockout js?
我正在研究这个项目原型。当前部分正在处理 "Multiple binding" 问题与敲除 js。我已经阅读了不同的方法,包括在 HTML 中引用数据模型时使用 "with" 语句。我还读到,在处理要呈现的各种数据模型时,使用 clearNode 可能是另一种可能的解决方案。以下是关于我当前问题的一些事实。
- 我使用了两个不同的数据模型,每个模型都是使用两个不同的 JSON responses/file(本地和 api)
创建的
- 第一个使用和呈现挖空绑定的模态是"questionDisplay"
- 我使用 google 文档捕获要包含在表单提交中的输入(无关紧要,但在代码中解释了一些计算)
- 在提交表单的过程中,信息被发送到一个 google 驱动器文件,一个 "next" 按钮将触发 "resultDisplay" 模式
- 此时出现问题,我得到 "Multiple bindings"
我已经尝试使用 "with" 语句来 "pin-point" 每次敲除模板的确切模型,但我在想因为它们只在函数调用期间实例化它不会无障碍?我不知道如何开始重构代码才能使用 "with" 语句。
我也尝试过 clearNode,通过在根中包含一个 id 名称,其中 knockout 声明了数据模型的名称,在第二次 KO 渲染期间在 clearNode 中使用该 id ......我的想法是它会清除它然后重用相同的节点。尽管在我提供的代码片段中,我在清除节点中使用 "template",因为我尝试了每个节点,所以碰巧那是我尝试的最后一个节点 lol
我还读到,在“.applyBindings”期间,我也可以包含元素名称来包含它吗?我尝试了几件事都没有成功。
PS:我应该再次声明,这是原型代码,所以,超级乱。向 Nathan Fisher (https://whosebug.com/users/29467/nathan-fisher) 致敬!
JS
//functions.js
function resultDisplay() {
parseJsonWithSelect();
var self = this;
self.data = ko.observableArray(jresponse);
}
function questionDisplay() {
var self = this;
var mappedData = qna.map(function(item) {
item.optionGroupName = "optionGroup_" + item.questionId;
item.selectedAnswer = ko.observable();
return item;
});
self.data = ko.observableArray(mappedData);
}
function initResultDisplay() {
var dataModel = new resultDisplay();
ko.cleanNode("template");
ko.applyBindings(dataModel);
$("#searchResultDisplay").modal("show");
}
function initQuestionDisplay() {
$("#inBetween").modal("hide");
var qnaDataModel = new questionDisplay();
$("#questionsDisplay").modal("show");
ko.applyBindings(qnaDataModel);
}
HTML
<!-- Questions modal -->
<div
class="modal fade"
id="questionsDisplay"
tabindex="-1"
role="dialog"
aria-labelledby="questionsDisplayLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="questionsDisplayLabel">
QUESTIONS
</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div
class="modal-body"
data-bind="template: {name: 'template', data: $data}"
></div>
<script type="text/html" id="template">
<div class="diplay-frame" data-bind="foreach: {data: data, as: '_data'}">
<div class="question-box">
<h2 class="question" id="ques" data-bind="text: _data['question']"/>
<div data-bind="foreach: {data: _data['answers'], as: 'answer'}">
<input type="radio" id="ans" data-bind="checked: $parent.selectedAnswer, attr:{name: $parent.optionGroupName, value: $data}" />
<span data-bind="text: answer"/>
</div>
</div>
</div>
</script>
<button
type="button"
onclick="captureAnswers()"
class="btn btn-secondary"
data-dismiss="modal"
>
Next
</button>
</div>
</div>
</div>
<!-- Search result Display Modal -->
<div
class="modal fade"
id="searchResultDisplay"
tabindex="-1"
role="dialog"
aria-labelledby="searchResultDisplayLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="searchResultDisplayLabel">
Search Results
</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div
class="modal-body"
data-bind="template: {name: 'template', data: $data}"
></div>
<script type="text/html" id="template">
<div class="diplay-frame" data-bind="foreach: {data: data, as: '_data'}">
<div class="result-box">
<div class="bgtint"></div>
<section class="businesscard">
<div class="flip">
<div class="front">
<div class="logo">
<img class="profile_image" width="50px" height="50px" data-bind="attr:{src: _data['profile_image']}"/>
<h2 class="user_name" data-bind="text: _data['username']"/>
<div class="introduction">COMPANY NAME GOES HERE!</div>
<div class="arrow"></div>
</div>
</div>
<div class="userinfo">
<ion-icon name="call">PHONE</ion-icon>
<div class="name">
</div>
</div>
</section>
</div>
</div>
</script>
</div>
<div class="modal-footer">
</div>
</div>
</div>
`
是的,您不能对整个文档调用两次 applyBindings
并指望能侥幸逃脱 ;-) 但是这个方法确实可以将一个元素作为它的第二个参数,所以绑定只适用于那。所以在你的情况下,你会打电话:
ko.applyBindings(dataModel, document.querySelector('#searchResultDisplay'));
并且:
ko.applyBindings(qnaDataModel, document.querySelector('#questionsDisplay'));
我正在研究这个项目原型。当前部分正在处理 "Multiple binding" 问题与敲除 js。我已经阅读了不同的方法,包括在 HTML 中引用数据模型时使用 "with" 语句。我还读到,在处理要呈现的各种数据模型时,使用 clearNode 可能是另一种可能的解决方案。以下是关于我当前问题的一些事实。
- 我使用了两个不同的数据模型,每个模型都是使用两个不同的 JSON responses/file(本地和 api) 创建的
- 第一个使用和呈现挖空绑定的模态是"questionDisplay"
- 我使用 google 文档捕获要包含在表单提交中的输入(无关紧要,但在代码中解释了一些计算)
- 在提交表单的过程中,信息被发送到一个 google 驱动器文件,一个 "next" 按钮将触发 "resultDisplay" 模式
- 此时出现问题,我得到 "Multiple bindings"
我已经尝试使用 "with" 语句来 "pin-point" 每次敲除模板的确切模型,但我在想因为它们只在函数调用期间实例化它不会无障碍?我不知道如何开始重构代码才能使用 "with" 语句。
我也尝试过 clearNode,通过在根中包含一个 id 名称,其中 knockout 声明了数据模型的名称,在第二次 KO 渲染期间在 clearNode 中使用该 id ......我的想法是它会清除它然后重用相同的节点。尽管在我提供的代码片段中,我在清除节点中使用 "template",因为我尝试了每个节点,所以碰巧那是我尝试的最后一个节点 lol
我还读到,在“.applyBindings”期间,我也可以包含元素名称来包含它吗?我尝试了几件事都没有成功。
PS:我应该再次声明,这是原型代码,所以,超级乱。向 Nathan Fisher (https://whosebug.com/users/29467/nathan-fisher) 致敬!
JS
//functions.js
function resultDisplay() {
parseJsonWithSelect();
var self = this;
self.data = ko.observableArray(jresponse);
}
function questionDisplay() {
var self = this;
var mappedData = qna.map(function(item) {
item.optionGroupName = "optionGroup_" + item.questionId;
item.selectedAnswer = ko.observable();
return item;
});
self.data = ko.observableArray(mappedData);
}
function initResultDisplay() {
var dataModel = new resultDisplay();
ko.cleanNode("template");
ko.applyBindings(dataModel);
$("#searchResultDisplay").modal("show");
}
function initQuestionDisplay() {
$("#inBetween").modal("hide");
var qnaDataModel = new questionDisplay();
$("#questionsDisplay").modal("show");
ko.applyBindings(qnaDataModel);
}
HTML
<!-- Questions modal -->
<div
class="modal fade"
id="questionsDisplay"
tabindex="-1"
role="dialog"
aria-labelledby="questionsDisplayLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="questionsDisplayLabel">
QUESTIONS
</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div
class="modal-body"
data-bind="template: {name: 'template', data: $data}"
></div>
<script type="text/html" id="template">
<div class="diplay-frame" data-bind="foreach: {data: data, as: '_data'}">
<div class="question-box">
<h2 class="question" id="ques" data-bind="text: _data['question']"/>
<div data-bind="foreach: {data: _data['answers'], as: 'answer'}">
<input type="radio" id="ans" data-bind="checked: $parent.selectedAnswer, attr:{name: $parent.optionGroupName, value: $data}" />
<span data-bind="text: answer"/>
</div>
</div>
</div>
</script>
<button
type="button"
onclick="captureAnswers()"
class="btn btn-secondary"
data-dismiss="modal"
>
Next
</button>
</div>
</div>
</div>
<!-- Search result Display Modal -->
<div
class="modal fade"
id="searchResultDisplay"
tabindex="-1"
role="dialog"
aria-labelledby="searchResultDisplayLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="searchResultDisplayLabel">
Search Results
</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div
class="modal-body"
data-bind="template: {name: 'template', data: $data}"
></div>
<script type="text/html" id="template">
<div class="diplay-frame" data-bind="foreach: {data: data, as: '_data'}">
<div class="result-box">
<div class="bgtint"></div>
<section class="businesscard">
<div class="flip">
<div class="front">
<div class="logo">
<img class="profile_image" width="50px" height="50px" data-bind="attr:{src: _data['profile_image']}"/>
<h2 class="user_name" data-bind="text: _data['username']"/>
<div class="introduction">COMPANY NAME GOES HERE!</div>
<div class="arrow"></div>
</div>
</div>
<div class="userinfo">
<ion-icon name="call">PHONE</ion-icon>
<div class="name">
</div>
</div>
</section>
</div>
</div>
</script>
</div>
<div class="modal-footer">
</div>
</div>
</div>
`
是的,您不能对整个文档调用两次 applyBindings
并指望能侥幸逃脱 ;-) 但是这个方法确实可以将一个元素作为它的第二个参数,所以绑定只适用于那。所以在你的情况下,你会打电话:
ko.applyBindings(dataModel, document.querySelector('#searchResultDisplay'));
并且:
ko.applyBindings(qnaDataModel, document.querySelector('#questionsDisplay'));