使用淘汰赛验证进行表单验证

时间:2015-08-29 01:24:08

标签: forms knockout.js knockout-validation

我遇到了使用Knockout进行数据绑定的某些表单设计的架构问题。我在工作中有一个相当大的项目,为了简单起见,我们说我正在点击一个API端点(虽然不是RESTful)并且回到了JSON响应。我目前通过自定义映射函数运行此响应,以将所有属性转换为可观察对象。表单工作正常但我现在想要使用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"由于设置更改需要添加,我还没有注意到它。

这个例子非常人为,但我不想有任何知识产权问题,所以希望它有意义。实际应用程序要大得多,并且到同一端点的不同GET / POST可能会导致6或7种不同的状态。检查" X是否设置似乎不太可扩展/可维护?然后使用适当的规则将Y&S和Z的属性设置为空的可观察量,以防万一" (同样适用于其他可能的情况)。

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

编辑:

我已经接受了Roy的回答,因为它与我正在寻找的最接近,但为了更加清晰,想象一下这种情况。我点击了一个端点,该端点可以发回属性abcd(但始终是子集,绝不是完整集)。如果我返回ab,我可以轻松使用ko.mapping使其可观察,以防它们发生变化。但是,我需要做的是允许用户基本上摆脱b并选择c代替。我无法想到一个干净的方式来设置"页面加载时cd的可观察对象允许使用它们,如果用户想要使用它们。我唯一想到的是,我为我的应用程序中的所有可能字段设置了observable,即使90%的时间,其中一半不会被使用。或者我想我可以使用像邮箱这样的pubsub系统在运行时动态创建所需的observable。我知道使用observable有一些开销,但它们对我来说看起来相当轻巧,所以我不确定这些方法中哪一个最好"最好"当考虑到绩效和发展时间时。

1 个答案:

答案 0 :(得分: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>
&#13;
&#13;
&#13;

相关问题