作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为了简单起见,我有一个简单的数组。我想要做的是循环遍历数组的第一类问题,然后循环遍历数组的第二类问题,依此类推。
“答案”将是文本输入字段或单选按钮或其他任何内容。
如何在 knockout.js 中“嵌套”这两个循环?我不能把它分成两个数组,因为这样我就失去了两个循环之间的关系。
//knockout.js viewModel
function SurveyViewModel() {
var self = this;
self.EvaluationElement = ko.observableArray([
{category: "Category1", question: "Question #1"},
{category: "Category1", question: "Question #2"},
{category: "Category2", question: "Question #3"},
{category: "Category2", question: "Question #4"},
{category: "Category3", question: "Question #5"},
{category: "Category3", question: "Question #6"},
{category: "Category4", question: "Question #7"},
我想构建一个 View (HTML),它本质上是一个嵌套如下的表格:
<table>
<tr>
<th colspan="3">Category 1</th>
</tr>
<tr>
<td>Question #1</td>
<td>Answer</td>
<td></td>
</tr>
<tr>
<td>Question #2</td>
<td>Answer</td>
<td></td>
</tr>
<tr>
<td colspan="3">Category 2</td>
</tr>
<tr>
<td>Question #3</td>
<td>Answer</td>
<td></td>
</tr>
<tr>
<td>Question #4</td>
<td>Answer</td>
<td></td>
</tr>
<tr>
<td>Question #5</td>
<td>Answer</td>
<td></td>
</tr>
</table>
我正在尝试做这样的事情......有明显的错误,但希望它能传达我的想法。
<br>
<table class="table table-hover">
<tbody data-bind="foreach: EvaluationElement/Category">
<tr>
<td colspan="2" data-bind="text: category></td>
</tr>
<data-bind="foreach: EvaluationElement">
<tr>
<td data-bind="text: question"></td>
<td>Answer</td>
<td></td>
</tr>
<// close loop>
</tbody>
</table>
<br>
<button data-bind="click: submitSurvey">Submit</button>
最佳答案
您应该在您的 View 模型中重组您的数据,以保持您的 View 美观和简单。如果您的 View 需要每个类别的表体,这就是 View 模型数据应该反射(reflect)的内容。
要将问题列表重组为类别列表,您可以使用 Knockout 的 pureComputed
。
我们创建一个函数,将数据从 [ { category, question } ]
转换为 [ { category, questions: [ { category, question ] } ]
。
这非常类似于 groupBy
。编写分组函数的方法有很多种;如果您想了解有关不同方法的更多信息,请搜索“在 javascript 中按属性分组”。
有了新的结构, View 与您想要的格式非常相似:
function SurveyViewModel() {
var self = this;
self.EvaluationElement = ko.observableArray([{
category: "Category1",
question: "Question #1"
},
{
category: "Category1",
question: "Question #2"
},
{
category: "Category2",
question: "Question #3"
},
{
category: "Category2",
question: "Question #4"
},
{
category: "Category3",
question: "Question #5"
},
{
category: "Category3",
question: "Question #6"
},
{
category: "Category4",
question: "Question #7"
}
]);
self.categories = ko.pureComputed(function() {
// Assumes questions sorted by category
return self.EvaluationElement().reduce(
function(cats, q, i, qs) {
const prev = qs[i - 1];
if (!prev || prev.category !== q.category) {
cats.push({
category: q.category,
questions: [ q ]
});
} else {
cats[cats.length - 1].questions.push(q);
};
return cats;
}, []);
});
};
ko.applyBindings(new SurveyViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table>
<tbody data-bind="foreach: categories">
<tr>
<td colspan="2" data-bind="text: category"></td>
</tr>
<!-- ko foreach: questions -->
<tr>
<td data-bind="text: question"></td>
<td>Answer</td>
<td></td>
</tr>
<!-- /ko -->
</tbody>
</table>
关于javascript - 如何在 knockoutjs 中嵌套单个数组的循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51357110/
我是一名优秀的程序员,十分优秀!