Изменяемое свойство объекта [почему на странице не видны изменения в компоненте после изменения его состояния]

Здравствуйте. Помогите разобраться.
Есть код. При нажатии сочетания shift+alt хотелось бы перерисовывать клавиатуру с одной раскладки на другую. В консоли видно, что значение свойства mode меняется. Но в render() потом всё равно используется первоначальное значение.
https://repl.it/@Ambrance/keyboard

Тут несколько проблем:

У тебя есть метод render который только один раз синхронизирует состояние класса и состояние DOM при создании клавитатуры. После нет ничего что бы синхронизировало изменившееся состояние класса и DOM.

Бонус проблема: переключение между русской-английской происходит просто по ctrl

А что за связь с ctrl?.. Почему так реагирует? Я ведь явно пишу, какую комбинацию ожидаю

Возможно я должна вызывать его внутри объекта, но как это сделать, если заранее не известны аргументы…

Дело не в ctrl, а в самом подходе. Не нужно аккумулировать нажатые клавиши в сет. Задолбаешься обрабатывать это состояние корректно. У события нажатия есть флаги которые говорят о том какая клавиша нажата (типа зажат ли шифт или альт) вот на них и смотри:

document.addEventListener('keydown', (event) => {
	if (event.shiftKey && event.altKey) {
		alert('Opa!')
	}
})

Единственное что я не проверять кроссбраузерности тех свойств что использовал

изначально пробовала так, но что-то не получилось. Попытаюсь еще раз.

На самом деле есть несколько проблем. (в примере есть решение “в лоб”, вродь переключается и ререднерит)

  • Рендер надо запускать несколько раз исходя из начальной имплементации, а runOnKeys один раз.
  • фільтер і клір можна заменить на every + has
  • лучше иметь в классе функционал описивающий кнтейнер, и весь функционал инициализации. Я б посоветовал только класс принимать в контструкторе и строить на сонове него клаву.

П.С. Сорян если встрял в разговор, просто хотелось чуток чет подкодить . )))

Мысль я поняла, правда в примере не работает у меня, когда открываю.
Спасибо)

Норм практика для компонент передавать аргументов корневой узел компоненты и “прикапывать” его в инстансе класса.

Это позволит написать такой метод render, который будет “переносить” внутреннее состояние компонента в DOM узел из this. Структурно это должно выглядеть как-то так:

class Keyboard() {
	constructor(options) {
		this.domNode = options.domNode
		this.render()
		window.addEventListener('keyup', this.keyupHandler.bind(this))
	}

	changeMode() {
		// set new state
		this.render()
	}

	keyupHandler() {
		if (needToChangeMode) {
			this.changeMode()
		}
	}

	render() {
		// state -> DOM node
	}

}
1 лайк

Все правильно. Чем больше описаний перспектив одного и того же, тем проще понять о чем речь.

Это верный путь, его нужно “додавить”. Путь с аккумуляцией состояния в Set-e неправильный потому что ведет к хрупкому коду.

Делаю по вашему примеру. Правда пришлось сменить сочетание на shift+ctrl (не воспринимает shift+alt - может дело в линуксе), и keyup на keydown.
Всё равно рендерит английский вариант. Что я упускаю?
https://repl.it/@Ambrance/keyboard

Во-первых. Нужно подчищать DOM с предыдущего состояния. Сейчас новые кнопки просто добавляются к существующим.

Во-вторых я не вижу где ты используешь значения для кнопок из this.mode в render. Нужно жеж не this.keys, a this.mode.keys. Сейчас this.keys записывается один раз в конструкторе и последующие изменения this.mode никак на них не влияют.

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

Того, что в конструкторе есть this.keys = this.mode.keys; недостаточно? Нужно внутри метода явно писать this.mode.keys?
UPD: видимо так и есть… Объявления в конструкторе были лишними

Искренне благодарю! Наконец получилось)

1 лайк