在Meteor JS中更改输入字段值时执行Update调用的最佳方法?

时间:2014-09-24 14:18:25

标签: meteor

假设的例子 - 你有一个" Items"集合,其中每个项目都有数据和价格存储在数据库中。

该数量是输入字段。     

我们希望在数量变更时更新数据库 - 没有"提交"按钮。有多种方法可以解决这个问题。两个例子:

  1. 更新数据库"已更改":

    'change input.qty': function (evt) {
        var qty = $(evt.target).val();
        if (qty==null){
            qty=0;
        };
        Items.update(this._id,{$set:{quantity: Number(qty)}});
    },
    
  2. 更新数据库" keyup":

    'keyup input.qty': function (evt) {
        var qty = $(evt.target).val();
        if (qty==null){
            qty=0;
        };
        Items.update(this._id,{$set:{quantity: Number(qty)}});
    },
    
  3. 1更有效 - 它只在用户点击输入框外部后执行一次更新调用。但是,这会带来更糟糕的用户体验,因为更新不会反映在页面上,因为他们正在键入内容。 (例如,假设"价格"字段是根据您的输入数量反应计算的)

    2是一种更好的用户体验,但效率极低(即输入103.58会使FIVE数据库调用)

    是否有更好的选择或良好的中间立场?

4 个答案:

答案 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);
}