假设的例子 - 你有一个" Items"集合,其中每个项目都有数据和价格存储在数据库中。
该数量是输入字段。
我们希望在数量变更时更新数据库 - 没有"提交"按钮。有多种方法可以解决这个问题。两个例子:
更新数据库"已更改":
'change input.qty': function (evt) {
var qty = $(evt.target).val();
if (qty==null){
qty=0;
};
Items.update(this._id,{$set:{quantity: Number(qty)}});
},
更新数据库" keyup":
'keyup input.qty': function (evt) {
var qty = $(evt.target).val();
if (qty==null){
qty=0;
};
Items.update(this._id,{$set:{quantity: Number(qty)}});
},
1更有效 - 它只在用户点击输入框外部后执行一次更新调用。但是,这会带来更糟糕的用户体验,因为更新不会反映在页面上,因为他们正在键入内容。 (例如,假设"价格"字段是根据您的输入数量反应计算的)
2是一种更好的用户体验,但效率极低(即输入103.58会使FIVE数据库调用)
是否有更好的选择或良好的中间立场?
答案 0 :(得分:5)
这是创建_.throttle
方法的确切情况。
'keyup input.qty': _.throttle(function (evt) {
...
}, 350),
当您使用_.throttle
这样的方式包装处理程序时,即使输入更频繁地更改,它也会在给定的毫秒数内被调用一次。
350
是一个很好的值,但确切的最佳值可能取决于您正在设计的界面。
答案 1 :(得分:3)
抄袭@Hubert OG的答案,除了推荐" debounce"而不是函数,"输入" &安培; "变更"事件。 (_.debounce
的工作原理与@Dave中没有样板的公认解决方案相同。)
这是创建_.debounce
方法的确切情况。
'input input.qty, change input.qty': _.debounce(function (evt) {
...
}, 350),
当你以_.debounce
方式包装你的处理程序时,它将在所有输入停止后被调用一次(至少给定的毫秒数)
答案 2 :(得分:2)
以下是我通常如何解决此问题:
var handle = null;
------------------------
'input input.qty': function (evt) {
var self = this;
if (handle)
clearTimeout(handle);
handle = setTimeout(function () {
var qty = $(evt.target).val();
if (qty==null){
qty=0;
};
Items.update(self._id,{$set:{quantity: Number(qty)}});
}, 500);
},
您可以使用500号玩法来满足您的喜好。使用此解决方案,当用户停止输入500毫秒时,您将只获得数据库调用。
我也会切换到input event,它会处理剪切,粘贴和关键条目。
答案 3 :(得分:0)
两者似乎都是很好的解决方案。在我看来,第一个更好 - keyup还注册了诸如按Enter或其他键之类的东西。由于我有多个具有多个数量字段的项目,所以我最终选择的是:
var handle = [];
'input input.qty': function (evt) {
var id = this._id;
if (handle[id]){
clearTimeout(handle[id]);
}
handle[id] = setTimeout(function () {
var qty = $(evt.target).val();
Items.update(id,{$set:{quantity: Number(qty)}});
}, 750);
}