yandex-ui / noscript

Noscript: JavaScript MVC Framework for building SPA
http://yandex-ui.github.io/noscript/
MIT License
34 stars 22 forks source link

[ns.Events] Неверно работает ns.Events.once #607

Closed iEgit closed 8 years ago

iEgit commented 8 years ago

ns.events.off не отписывает once события. Пример

const say = () => console.log('yo')
ns.events.once('yo', say)
ns.events.off('yo', say)
ns.events.trigger('yo')

// says 'yo'

Добавил ссылку на оригинальный обработчик и поправил off.

iEgit commented 8 years ago

@vitkarpov @i2r

vitkarpov commented 8 years ago

@chestozo @Katochimoto

vitkarpov commented 8 years ago

👍

chestozo commented 8 years ago

Круто, но для полноты надо поддержать двойной .once(), кажется, сейчас будут проблемы с перезатиранием __original.

alexeyten commented 8 years ago

С двойным once проблемы нет. Есть спецэффекты если я одну и ту же функцию добавлю через on и once, а потом вызову off на неё один раз. Удалится первая из добавленных функций, это может быть неожиданно.

iEgit commented 8 years ago

@chestozo проблемы не будет. Поговорили с @alexeyten, есть такая проблема.

const say = () => console.log('yo')
ns.events.once('yo', say)
ns.events.on('yo', say)
ns.events.off('yo', say) // снимет обработчик once, а не on

Cошлись на том, что с этим можно жить и достаточно описать эту особенность в документации.

Что думаете?

vitkarpov commented 8 years ago

А какое поведение ожидаемое в данном случае? Кажется, что должен снять оба обработчика, да?

alexeyten commented 8 years ago

@vitkarpov в том-то и дело, что любое будет неожиданным. Раньше .off снимал первый .on, но они все были одинаковые так что не было особенных проблем.

А вообще я с трудом представляю зачем может быть надо добавать одну и ту же функцию дважды.

vitkarpov commented 8 years ago

Ну, т.е. такой ситуации, как ты описал, по идее, не должно быть?

vitkarpov commented 8 years ago

В реальной жизни

alexeyten commented 8 years ago

Не должно. Поэтому я и предложил не пытатья её решить, а просто задокументировать, что поведение будет странным и что не нужно добавлять одну и ту же функцию в обработчики событий дважды

alexeyten commented 8 years ago

UPD: а, нет, не будет

vitkarpov commented 8 years ago

Ну и ок 👍

alexeyten commented 8 years ago

:+1:

chestozo commented 8 years ago

@alexeyten

А вообще я с трудом представляю зачем может быть надо добавать одну и ту же функцию дважды.

к примеру, по ошибке предлагаю в on() и в once() делать проверку и кидать warning, к примеру

@iEgit: Давай добавим тестов на:

alexeyten commented 8 years ago

предлагаю в on() и в once() делать проверку и кидать warning, к примеру

Если только в DEV-сборке (как react и т.п.)

vitkarpov commented 8 years ago

Если только в DEV-сборке (как react и т.п.)

Есть ns.log.error — он как раз так и работает

vitkarpov commented 8 years ago

@iEgit ping? поправишь по комментариям, докинешь тестов:

iEgit commented 8 years ago

да, доделаю

iEgit commented 8 years ago

предлагаю в on() и в once() делать проверку и кидать warning, к примеру

А на что проверку? На то, что уже есть такой обработчик где-то?

iEgit commented 8 years ago

тесты добавил

vitkarpov commented 8 years ago

👍 @chestozo ?

chestozo commented 8 years ago

А какое поведение ожидаемое в данном случае? Кажется, что должен снять оба обработчика, да?

Я думаю мы ориентируемся на jquery. Там поведение такое - оба обработчика будут отписаны:

var $body = $(document.body);
var handler = function() {
    console.log(+new Date());
};

$body.one('click', handler);
$body.on('click', handler);

$body.off('click', handler);

$body.trigger('click');
// Ничего не происходит
chestozo commented 8 years ago

Может допилим до поведения "как в jquery"?

iEgit commented 8 years ago

А ты уверен, что нужно ориентироваться на эту великую технологию?

vitkarpov commented 8 years ago

Там поведение такое - оба обработчика будут отписаны

Вообще, кажется, логичным чтобы once и on в этом смысле работали одинаково, за тем лишь исключением, что once один раз выполнится.

Т.е. должно быть аналогично случаю:

foo.on('event', handler);
foo.on('event', handler);

foo.off('event', handler);

Сейчас это не так?

chestozo commented 8 years ago

А ты уверен, что нужно ориентироваться на эту великую технологию?

Пока используется jquery - лучше бы поведение наших эвентов было бы максимально аналогичным.

Сейчас это не так?

А я не знаю, давайте напишем тест :)

vitkarpov commented 8 years ago

А я не знаю, давайте напишем тест :)

https://github.com/yandex-ui/noscript/pull/607/files/a2917b0895c83c97132382849dd15099b23e680a#diff-99f6436afe06f3898363ed5e9798b602R144 — а вот есть тест на двойной once и off.

Работает консистентно с текущим поведением on:

Они сейчас все хранятся в одном массиве плоским списком, как только нашли первый handler, то удаляем его из массива и делаем break.

Мы не можем сделать поведение как в jquery, мы должны сделать как в ns.Events :)

chestozo commented 8 years ago

Поговорили голосом - завёл #613 По этой issue 👍 :)