事件映射中的 _.debounce 和 Iron.controller()

_.debounce and Iron.controller() in eventmap

我想使用 iron-router 实现去抖动搜索,其中搜索查询被写入控制器状态。不幸的是,我能让 _.debounce 工作的唯一方法是像这样将它直接传递给事件映射:

Template.search.events({
  'keydown #search': _.debounce(function(event) {
    var controller = Iron.controller();
   }, 750)
});

不幸的是 Iron.controller() 不知道这里的上下文,所以会出现错误。

但是如果我将 debounce 嵌套在函数中以获得 Iron.controller(),_.debounce 永远不会触发。

Template.search.events({
  'keydown #search': function(event) {
    var state = Iron.controller().state;
    var q = $(event.currentTarget).val();
    _.debounce(function() {
      state.set("q", q);
    }, 750);
  }
});

有没有人做过类似的事情并解决了这个问题?

我不熟悉 debounce,但如果我没记错的话,以下内容应该有效:

var doIt = _.debounce(function(func){
    func()
}, 750);

Template.search.events({
  'keydown #search': function(event) {
    var state = Iron.controller().state;
    var q = $(event.currentTarget).val();
    doIt(function(){
        state.set("q", q);
    })
  }
});

我发现 iron-router 使用了相当多的裸 this throughout the code.

可能是您对事件处理程序去抖时未正确设置范围。如果是这种情况,您可以尝试将其绑定到 this:

Template.search.events({
  'keydown #search': _.debounce(function(event) {
    var controller = Iron.controller();
   }.bind(this), 750)
});

也许它应该绑定到 events。我不确定,因为我不熟悉这个库。

至于第二个示例,正如 Peppe L-G 正确建议的那样,debounce 通过返回 去抖函数 来工作。在您的示例中,您永远不会调用它!

a = function(){};
b = _.debounce(a, 200);
a() // immediate
b() // waits 200 millis, calls a()

此外,重要的是要注意您不应 声明 事件处理程序中的去抖函数。否则,您将始终创建一个新的去抖功能,并且所有这些功能都会在第一次机会时触发,从而破坏了目的。

我建议您更恰当地命名去抖处理程序。例如:

var handleKeydownEventDebounced = _.debounce(function(controller, query){
    controller.state.set("q", query);
}, 750);

Template.search.events({
  'keydown #search': function(event) {
    handleKeydownEventDebounced(Iron.controller(), $(event.currentTarget).val());
  }
});