_.debounce и Iron.controller() в карте событий

Я хочу реализовать искаженный поиск с помощью 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);
  }
});

Кто-нибудь сделал что-то подобное и решение этой проблемы?

2 ответа

Решение

Я не знаком с 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);
    })
  }
});

Я обнаружил, что железо-маршрутизатор использует изрядное количество голых this по всему коду.

Возможно, область действия не установлена ​​правильно, когда вы отклоняете обработчик событий. Если это так, вы можете попробовать связать его с this:

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

Может быть, это должно быть связано с events, Я не уверен, так как я не знаком с этой библиотекой.

Что касается второго примера, как правильно подсказывает Peppe LG, debounce работает, возвращая испорченную функцию. В вашем примере вы никогда не называете это!

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

Также важно отметить, что вы не должны объявлять функцию debounce внутри обработчика событий. В противном случае вы всегда создадите новую опровергнутую функцию, и все они сработают при первой возможности, победив цель.

Я рекомендую, чтобы вы назвали ваш отклоненный обработчик более подходящим. Например:

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());
  }
});
Другие вопросы по тегам