# jquery + emit ## Проблема Сейчас разметка в нашем коде создаётся в одном месте, а модифицируется в другом. Пример с focus row: ```javascript _createRow: function(row) { const $row = this.callBase.apply(this, arguments); if(this.option('focusedRowEnabled') && row) { if(this.getController('focus').isRowFocused(row.key)) { // создание разметки для сфокушённой строчки $row.addClass(ROW_FOCUSED_CLASS); } } return $row; } // ... // миллион строчек // ... updateFocusedRow: function(change) { // ... that._clearPreviousFocusedRow($tableElement, focusedRowIndex); const $row = that._prepareFocusedRow(/* ... */); // ... } ``` Код находится в разных местах, отыскать откуда обновляется какой-то элемент сложно Причём иногда мы можем некорректно обновить/забыть обновить вообще ## Возможное решение Можно перенести обновление и инициализацию разметки в одно место. Так как мы уже повсюду используем jquery объекты, можно прямо их заэкстендить. Вместо того чтобы при рендере возвращать просто jquery элемент, возвращать его + метод по обновлению разметки по состоянию Условно, было: ```javascript _renderCell: function(content) { const $td = $('<td>'); $td.text(content); return $td; } ``` Стало: ```javascript _renderCell: function(content) { const $td = $('<td>'); $td.text(content); $td.update = (content) => { $td.text(content); } return $td; } ``` Вместо использования обычных замыканий можно использовать observable, чтобы удобнее было работь при большом стейте ## В чём плюсы - несложно интегрировать в текущий проект, не надо глобально менять много мест в коде, т.к. эти объекты совместимы с обычными jquery - мы на самом деле не будем добавлять новой логики, а просто перенесём логику по обновлению разметки из onOptionChanged и других методов поближе и инициализации разметки — будет лучше инкапсуляция работы с dom'ом - чем больше перепишем на этот подход с использованием observable, тем меньше нужно будет думать над механизмом renderChangesOnly - повысится инкапсулированность разметки, код будет похож на фреймворковский ## В чём минусы - нужно будет написать немного утилитных методов для корректного обновления разметки - к примеру для работы обновления массивов (td'шек в строчке к примеру) - или для conditional rendering - выглядит как костыльный реакт ## Как проверить Для того чтобы проверить гипотезу, что это работает, можно попробовать использовать её в механизме рендеринга строк и избавится от сложного renderChangesOnly механизма ## Примеры кода (осторожно, возможно нечитаемо :D) - https://codepen.io/pomah33/pen/poObYNb?editors=1010 - https://codepen.io/pomah33/pen/LYJZaWr?editors=1010 ## Прочее - у нас уже есть методы watch https://github.com/pomahtri/devextreme/blob/1c13a44145e048d7ac91aecd9cc3eb8de379a5ee/js/ui/grid_core/ui.grid_core.columns_view.js#L715 я не знаю что это такое