finom/seemple

Matreshka#mediate - doesn't work when user types numbers

Closed this issue · 16 comments

http://jsfiddle.net/bn7tp76m/2/

Функция которая передается в mediate срабатывает, но не меняет значение, до тех пор пока не введешь в поле какую-нибудь букву.

Как увидеть проблему по ссылке выше:

  1. Ввести в инпут "0000"
  2. В консоле покажется результат функции переданной в mediate, которая делает parseInt - 0
  3. В инпуте по прежнему "0000"
  4. В любое место инпута ввести символ, отличный от 0-9
  5. Результат выполнения функции переданной в mediate покажется в инпуте, только после 4п.

Обнаружил на тестах

finom commented

Это предсказуемое состояние. Фреймворк видит, что значение свойства не изменилось (как было нулем, так и осталось) и не меняет состояние ноды в угоду производительности. Раньше инпут перезаписывался еще раз при вводе и это вызывало некоторые серьезные проблемы с UI. Я пока не знаю, как решить вашу проблему, кроме как лезть в ядро фреймворка. Это принципиальный вопрос? Могу подумать, как это исправить к выходу 1.1.

Ну а если вводить не "0000", а например "002678", потом еще цифры добавлять, "00267802" - значение свойства "int" меняется, и в инпуте должно быть "267802" - срабатывает событие change, и в свойстве "int" уже другое значение, и все равно в привязанном к "int" инпуте значение не меняется

finom commented

Хм, логично. Спасибо за репорт.

Не подскажите как это можно исправить, костылем хотя-бы ?

Еще есть предложение, реализовать в ядре для mediate цепной вызов функций. Чтобы можно было задать несколько медиаторов для одного свойства, которые будут вызываться цепочкой.

Вот как я это сейчас реализовал: http://jsfiddle.net/14L66txd/3/

finom commented

Вот такой костыль :(

app.on('input::int', function(){
    app.bound('int').value = app.int;
});

Еще есть предложение

Не совсем понимаю, какую задачу это решает.

Спасибо!

Такой подход позволяет задавать несколько фрагментированных трансформаций, позволяет динамически добавлять новые трансформации - когда это необходимо, не убирая при этом старые

finom commented

@undermuz так ведь можно создать массив функций а в mediate его прогонять.

Да, я так и сделал - и скинул выше пример. Думал такой функционал будет полезен в ядре :)
У меня в некоторых проектах это было необходимо, а для других не помешало бы из коробки.

finom commented

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

Matreshka.prototype.myMethod = function() {};
...
this.myMethod();
finom commented

Бага в особенностях JS:

'0005' == 5 // true

Думаю, может, какой-нибудь новый флаг добавить (для 4 аргумента bindNode), говорящий о том, что "когда значение свойства изменилось, меняй ноду, даже если источником изменений стала сама нода" или "заставить всегда переустанавливать значение ноды". Пока хорошего решения нет, к сожалению.

Может флаг строго сравнения?
Это не баг JS, просто сравнение не строгое. вот так в данном случае надо: '0005' === 5 //false

Или передавать тип: app.bindNode( 'x', ',x' ); app.setType('x', 'string')
Или функцию: app.setType('x', String) и тогда сравнивать будет так:
xTypeFn( '0005' ) == xTypeFn( 5 )

Самый простой вариант это конечно строгое сравнение, но я не знаю как это отразится на остальной логике фреймворка

finom commented

Пришлось использовать грязный хак, к сожалению.

finom commented

Ух, как эта проблема испортит мне статистику закрытия issue...

@finom, вы писали что "Пришлось использовать грязный хак, к сожалению.", но в версии 1.3.2 проблема актуальна.

И костыль мне не помог:

app.on('input::int', function(){
    app.bound('int').value = app.int;
});
finom commented

@undermuz сорри, забыл сказать, что релиз выйдет немного позже. http://jsfiddle.net/bn7tp76m/4/ -- вот результат с новой версией, которую можно взять из бнанча develop. Наверно, неправильно было закрывать эту проблему, переоткрываю до релиза.

Спасибо. Версия из примера работает =)