2

示例 jsFiddle

我仍然倾向于 knockout.js,所以请随时提出改进我的代码的建议


ko.mapping用来从包含以下结构的 JSON 字符串生成我的视图模型:

questions: [
    answer: "whetever the user enters", 
    controlType: "the type of input to display",
    lookupItems: "anything that will go into a SELECT input",
    modalSection: "if this question is a modal, then all modal questions will go here"
]

我已经设法让一切正常,并且通过遵循这个处理模态的示例,设法让我的模态和相应的问题按照我的意愿弹出。

然而,我的问题是如何从这个模式中保存多个结果?用户应该能够多次调出模式并添加他们想要的尽可能多的信息 - 然后应该在问题下方显示。

这是我到目前为止所尝试的:

.submissions数组添加到modalSection

扩展 my.modalSection使其上有一个提交集合,因此当用户在模式上单击“确定”时,它会将当前模式的副本添加到此集合中,然后应显示在我的表中:

<!-- ko foreach: modalSection.submissions -->
<table>
    <tbody data-bind="foreach: questions">
        <tr>
            <td data-bind="text: text"></td>
            <td data-bind="text: answer"></td>
        </tr>
   </tbody>
</table>
<!-- /ko -->

这是我尝试这个的小提琴版本

然而,这似乎不起作用,我的桌子仍然无人居住。即使那样,如果我确实让这个工作,我什至会朝着正确的方向前进 - 我不会只是存储modalSection多次相同的可观察实例吗?

谁能指出我正确的方向,也许看看提供的小提琴中的代码,并就我可以改进的地方以及如何到达我想去的地方给出任何指示?


编辑 1

为了更好地理解我想要实现的目标,这是一个场景。

说有两个问题:

  1. 你曾经拥有过汽车吗?
  2. 请提供您拥有的所有汽车的详细信息,包括品牌、型号和颜色。

所以我的第一个问题是一个下拉列表(其中lookupItems是 [Yes] 和 [No])。第二个问题需要更多细节,因此它使其成为模态的主要候选者,因此该问题将有一个按钮作为其输入,可能标记为 [添加汽车]。

这将提出一个带有问题的模态(具有控制类型等,就像非模态问题一样)[汽车的品牌是什么?],[型号是什么?]和[颜色是什么?]。填充模式后,结果将填充到某处(如表格),并且 [添加汽车] 按钮将再次可用以添加 N 更多详细信息。

4

1 回答 1

2

在开始之前,我想说我认为该指南未能实现将 DOM 操作与视图模型分离的目标。有几个 DOM 访问实例

var hiddenDiv = document.createElement('div');
    hiddenDiv.style.display = 'none';
    document.body.appendChild(hiddenDiv);
...
$(hiddenDiv).remove();
...
$rendered.dialog('close');

所有这些都打破了我们的关注点分离。有很多方法可以做到这一点,但这意味着彻底检查你的代码。我会回到这个。

您的代码有问题(以下解决方案)

  1. HTML 中以<!-- ko if: modalSection.submissions -->loops over开头的部分"foreach: modalSection.questions"。这里的问题是它不会显示 的集合submissions,这是您粘贴模态结果的地方。即使您正确输入结果,它们也不会显示。
  2. 您正在从 HTML 中收集 JSON。这不是斯巴达,这是疯狂。
  3. 在 OK 对话框中,您将添加submissions为 observableArray。这不起作用,因为 Knockout 已经为视图模型应用了绑定。
  4. 您正在push将对话的结果添加到可观察对象的数组中,这不会引发可观察到的变化
  5. 您没有复制对话结果,您只是将其添加到submissions

代码解决方案

  1. 这里需要两个循环。一个外循环submissions,一个内循环questions
  2. 我猜您的服务器正在以某种方式将此 JSON 粘贴到 HTML 中。特定服务器的解决方案会有所不同,但您应该能够将 JSON 粘贴到script标签中,将其存储在变量中,然后直接使用它。DOM 不适用于数据。
  3. 您需要submissions在原始 JSON 中有一个属性,以便 Knockout 映射会在原始应用绑定之前为您创建一个 observableArray。
  4. 像这样添加到可观察数组中:submissions.push(item). 是在括号之前push的可观察对象上,而不是之后。
  5. 复印一份。ko.toJS将打开一个可观察的视图模型并为您插入一个标准的 javascript 对象。然后你可以调用ko.mapping.fromJS它,你有一个干净的副本。

工作小提琴

进一步说明

仍然存在对话框结果没有被重置的问题。您可以通过多种方式处理此问题,但我真正鼓励您研究其他处理对话框的方法,以免在视图模型中弄乱 HTML。Ryan Niemeyer 有一个很棒的小提琴演示了视图模型使用的jQuery 对话框。这是基本的,但它应该为您指明正确的方向。


编辑

这是另一个小提琴,重做。视图模型中的 DOM 访问为零,我使用 Niemeyer 的对话框绑定与模态对话。我没有使用映射插件,因为我认为当你的视图模型有行为时它会让你更加努力。

如果您对此有任何疑问,请告诉我。

于 2013-07-30T19:06:40.973 回答