【问题标题】:Form validation with Knockout Validation使用 Knockout Validation 进行表单验证
【发布时间】:2015-11-23 18:00:49
【问题描述】:

我遇到了一些使用 Knockout 进行数据绑定的表单设计的架构问题。我有一个相当庞大的项目在工作,为了简单起见,假设我正在访问一个 API 端点(虽然不是 RESTful)并返回一个 JSON 响应。我目前正在通过自定义映射函数运行此响应,以将所有属性转换为 observables。表单工作正常,但我现在想使用 Knockout Validation 添加验证。我们还没有构建所有不同的规则,但我希望深入了解的答案是通过我的可观察地图添加规则的最佳方式。另一个令人头疼的是,返回的响应具有根据服务器上可以在 UI 中更新的某些设置而变化的属性,因此我不会为我可能需要的东西准备好可观察的。我知道这非常令人困惑,所以也许一个模糊的、人为的例子会有所帮助:

前提条件:设置X在页面加载时启用

JSON 响应:

results: [
  { a: 1 },
  { b: 2 },
  { c: 3 }
]

处理:

var arr = ko.observableArray([]);

$.get('/endpoint/').then(function(data) {
  data.results.forEach(function(result) {
    arr.push(mapToObservables(result));
  });
});

设置Y启用,属性“c”不再相关但“d”是,所以需要返回的JSON是:

updates: [
  { a: 1 },
  { b: 3 },(updated value)
  { d: 4 } (new value)
]

我最初观察属性“a,b,c”,所以“a,b”很好,因为它们的状态仍然是已知的。但是由于设置更改,需要添加属性“d”,而我还没有关注它。

这个例子非常做作,但我不想遇到任何 IP 问题,所以希望它有意义。真正的应用程序要大得多,对同一端点的不同 GET/POST 可能会导致 6 或 7 个不同的状态。检查“是否设置了 X?然后将 Y 和 Z 的属性设置为具有适当规则的空 observables,以防万一”似乎不太可扩展/可维护(对于其他可能的情况也是如此)。

我真的希望这对可以指导我的人有一点意义。我进入这个项目时甚至不知道 Knockout 是什么或以前的应用程序是如何工作的,所以试图吸收所有相关知识有点疯狂。提前谢谢大家!

编辑:

我接受了 Roy 在下面的回答,因为它最接近我正在寻找的内容,但为了更清楚一点,请想象一下这种情况。我遇到了一个可以发回属性a、b、c 或d 的端点(但总是一个子集,而不是完整集)。如果我返回a 和b,我可以轻松地使用ko.mapping 使它们可以被观察到,以防它们发生变化。但是,我需要能够做的是让用户基本上摆脱b 并选择c,例如。如果用户想使用它们,我想不出一种干净的方法来在页面加载时为c 和d “设置”可观察对象以允许它们使用。唯一想到的是我为我的应用程序中所有可能的字段设置了可观察对象,即使在 90% 的情况下,其中有一半不会被使用。或者我想我可以使用像邮箱这样的 pubsub 系统在运行时动态创建所需的 observables。我知道使用 observable 会产生一些开销,但它们对我来说似乎相当轻量级,所以当同时考虑性能和开发时间时,我不确定这些方法中哪一种是“最好的”。

【问题讨论】:

  • 我不确定,但我想你想看看ko.mapping.fromJS,它将从 JS 对象成员创建 observables。
  • 感谢您的回答,不幸的是它并没有真正解决这个问题。我的映射插件运气不佳,所以我编写了自己的方法来映射 JSON 响应中的 observables,但考虑到最初可能不会从服务器返回的属性是我的困难所在。我将暂时保留这个问题,但我很感谢您的回复。
  • 我将创建所有属性作为可观察对象,并为每个属性创建一个标志(可观察)以指示它是否正在使用。
  • @RoyJ 抱歉,我有段时间没上,但这是个好主意。我会弄乱它,看看我能想出什么。我们的时间不多了,这只是大约 30 页的一页,所以我可能不得不拼凑一些东西然后继续前进。不过,如果我想出任何天才的想法,我会回来分享。再次感谢您的帮助!

标签: forms knockout.js knockout-validation


【解决方案1】:

这是您正在寻找的那种行为吗?

var d1 = {
  a: 1,
  b: 2
};
var d2 = {
  a: 'oo',
  c: 'ah'
};

var vm = {
  data:ko.observable()
  };
vm.data(ko.mapping.fromJS(d1));
setTimeout(function() {
  vm.data(ko.mapping.fromJS(d2));
}, 1000);


ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<div data-bind="if:data().a">A:<span data-bind="text:data().a"></span>
</div>
<div data-bind="if:data().b">B:<span data-bind="text:data().b"></span>
</div>
<div data-bind="if:data().c">C:<span data-bind="text:data().c"></span>
</div>

【讨论】:

  • 这与我正在寻找的内容相似,我将接受它作为答案,因为我的问题相当模糊。不过,我已经编辑了我的原始帖子,更加清晰,如果您有任何其他想法,我全神贯注!谢谢:)
猜你喜欢
  • 2017-02-04
  • 2013-03-31
  • 1970-01-01
  • 2013-04-20
  • 2014-05-11
  • 2012-12-02
  • 2014-09-08
  • 1970-01-01
  • 2011-12-26
相关资源
最近更新 更多