-
Notifications
You must be signed in to change notification settings - Fork 22
Next
-
Model. Отличие от дарьевских хэндлеров -- хэндлер это набор моделей с одинаковым id. Т.е., скажем, все списки писем в почте это один хэндлер. В noscript'е -- каждый список писем (т.е. с определенными параметрами) это одна модель. Это инстанс класса Model, со своими методами и т.д. Данные модели можно менять при помощи специальных методов, после чего она генерит на себе события, на которые можно подписывать (например, блок их слушает). doochik: как получить все модели данного типа и что-то с ними сделать?
-
Request. Запрос нужных моделей с сервера.
-
View. Block в терминах дарьи. Боксы это части View теперь. В боксе может быть больше одного видимого элемента.
-
Layout. В дарье боксы контролировались через специальные методы (selectName), которые по params говорили, какой именно блок они собираются показать. Плюс у каждого блока были описаны его потомки. В noscript'е лэйаут описывается декларативно для каждой страницы. Это устраняет проблему, когда изменение метода selectName для добавления (например) новой страницы, ломает какую-то еще страницу. doochik: layout зависит не только от page. и еще у нас есть такое динамическое вычисление
.selectName = function(params) {
if (params._page != "setup") { return; }
if (params.tab && Block._info["setup-" + params.tab] ) {
return "setup-" + params.tab;
}
return "setup-index";
};
**edoroshenko**: плюсую. У нас в Диске вообще только один layout. При этом, мы в боксе показываем разные блоки.
-
Router. Решает, какой лэйаут нужно выбрать для данного урла. Плюс парсит урл в набор параметров.
-
Update. Перестраивает страницу в соответствии с новыми параметрами. Вопрос: нужны ли локальные апдейты? doochik: да
doochik Вообще, с событиями от model и биндингами в view вроде бы отпадает необходимость в ручном запуске run. Он должен запускаться глобально при:
- изменении параметров страницы
- при изменении model на видимых view
Где Actions?
doochik: еще мы сделали, что updater ставит jquery-data на каждую ноду View, поэтому Action может получить контекст клика (ссылку на конкретный инстанс View), а View может получить инстанс родителя. Получилось очень удобно, ведь не надо знать структуру дерева из Updater.
-
Коллекции. Возможно, Model.Collection и View.Collection. Нечто для реализации, например, слайдера для фоток или бесконечного списка писем. Со стороны сервера есть ручки, возвращающие куски списка (постранично или с указанием произвольного диапазона). Модель (Model) умеет хранить "разряженный" список таких кусков, дозапрашивать при необходимости недостающие и формировать данные для шаблонизации. Блок (View) умеет отображать нужные (видимые) куски, дорисовывать недостающее, удалять лишнее (чтобы не хранить в DOM'е тысячи элементов).
doochik:
- хочется ViewCollection для реализации бесконечного списка с пейджером, т.е. один view соддержит массив однотипных view, у которого итеративно (может и не итеративно) меняются параметры, например, page_number
- хочется иметь комбинацию из viewcollection + subview. Это когда пункт 1, но каждый элемент в view еще может раскрываться в свое дерево (например, список писем -> [письмо1, письмо2] -> тело письма)
-
Вдогонку. Нужно уметь автоматически распиливать модель-коллекцию на модель с индексами и набор собссно моделей с данными (например, messages -> [ message ]). Хочется делать это как-то более-менее автоматически.
Нужно задать:
-
На какие именно модели нужно распиливать коллекцию (конструтор, id, ...). Вопрос: должны ли быть коллекции всегда быть однородными (наверное, да).
-
Указать jpath, по которому будет располагаться массив с данными для моделей.
-
Указать, как именно доставать параметры моделей из этих кусков данных. Объект типа jresult.
-
Под какими индексами сохранять эти модели.
-
-
Многоступенчатая загрузка моделей. Т.е. данные из результатов одного реквеста формируют параметры для следующего.
-
Возможность перерисовывать не весь блок целиком. Плюс для коллекций возможность перерисовать выборочно несколько элементов коллекции. Для обычных блоков нужно уметь перегенерять совсем мелкие куски (флажок в списке писем, новая метка, лайк у фотки и т.д.). Возможно, современные браузеры уже достаточно быстрые, чтобы перерисовывать более крупные куски (померять!). В любом случае, нужно полностью отказаться от ручной модификации html'я блока. Все изменения должны идти через изменения моделей, а блок должен слушать события от соответствующих моделей. Причем, для сложных моделей (фотка, письмо, и т.д.) должны генериться (и слушаться) события не только об изменении модели целиком, но и для изменения части модели (флажок и т.д.).
Как. Примерно так я это себе вижу:
-
В html-е блока размечаются subview. Через соответствующий класс:
<div class="view view-message"> ... <div class="subview subview-message-labels"> ... </div> ... </div>
В терминах BEM это в общем-то элемент. Но не совсем. На деле это просто обертка над каким-то количеством DOM-нод, которые нужно уметь перерисовать.
-
В описании view добавляются условия, при которых нужно блок перерисовать. Видимо, проще всего это делать в терминах моделей.
subviews: { // Перерисовать subview labels, если у модели message поменялось что-либо по jpath'у .labels. 'message.labels': [ 'labels' ], // Перерисовать subview labels, если в модели labels поменялась метка с id совпадающим с одной из меток письма из message. 'labels.label[ .id == message.labels.label.id ]': [ 'labels' ] ... }
-
-
Несколько одинаковых блоков на странице. Сейчас в noscript'е нельзя показать одновременно два блока с одним id, но разными параметрами. Что насчет двух одинаковых блоков с одинаковыми же параметрами? По идее может пригодиться.
-
Несколько "ключевых" наборов параметров для блока. Причем в параметрах из урла могут присутствовать параметры из двух и более наборов, так что блок должен уметь выбирать, чем именно параметризоваться.
-
Анимация. Нужны анимации блоков при переходе между страницами. И нужны, возможно, глобальные (страничные) анимации (например, для мобильной почты).
-
Garbage Collector. При этом для блоков он должен быть таким, чтобы в боксах не хранить много элементов, а для моделей должен быть автоматическим -- т.е. если модель не нужна больше никакому блоку, то можно ее прибивать. Тут тонкий момент есть. Если модель напрямую не используется блоком, но она участвовала в построении параметров для него, то после ее прибития мы не сможем перерисовать блок (например, нажав на Back) без перезапроса.
-
"Транзакции" при изменении моделей. Например, мы хотим изменить несколько моделей. Каждое изменение тригерит событие, которые меняет блок (или несколько блоков). Нужно уметь все эти изменения склеить в один апдейт.
-
Undo. В целом вроде несложно. Нужно запоминать копии моделей до изменения. Плюс нужно обратное действие. Видимо, вычислить его из diff'а моделей будет нереально. Т.е. скажем, ставя флажок на письмо, нужно запомнить модель без флажка и действие "снять флажок", которое представляет собой id действия и набор параметров к нему. Не всякое действие обратимо, очевидно.
-
События на блоках а-ля наноблоки. Вообще, неплохо бы заюзать код для развешивания событий на наноблоки и в noscript'е. Помимо DOM-событий, нужны и кастомные события. Как блочные, так и глобальные. Или вообще сделать все блоки одновременно и наноблоками.
-
Наследование лэйаутов.
-
Нужен какой-то объект Page. Для хранения всякого про страницу. А то сейчас оно все размазано непонятно по каким переменным.
-
Клавиатурная навигация.
-
Шоткаты.
-
Возможно таки нужна возможность вычислять ключ модели/блока постфактум.
-
shirokoff: Хочется сложных зависимостей между блоками. Опишу ситуацию. В почте есть выборка писем за месяц. Письма подгружаются порциями в разных блоках и в DOM выстраиваются друг за гругом. Получается типа бесконечный список. Ниже отдельным блоком лежит пейджер. Когда из выдачи перестали приходитть письма за текущий месяц, надо в пейджере написать "Вы просмотрели все письма за ноябрь". Сейчас я это делаю через DOM. Это не правильно. Могут прийти новые письма за месяц и если их хватит на новый блок, то сообщение нужно убрать.
- Биндинг модели и view: меняешь свойство у модели -- автомитически обновляется view.
- doochik: сделать для model метод invalidate аналогичный view, когда данные остаются, но помечаются как невалидные
- doochik: хочется при запросе model передавать туда не params + models-list, а список ключей. Почему? Ключи уже есть в model/view и их не надо еще раз пересчитывать; ключи не надо будет рассчитывать на сервере; в запрос точно уйдут только указанные параметры и ничего лишнего
- doochik: для моделей сделать параметр last_usage и убивать кеши, которые долго не использовались
- doochik: также и для view, убивать ноды и инстансы, которые долго не показывались
- doochik: навешивание событий внутри view не через $.find.on, а декларативно, например, как в backbone. 1) Это упростит сам процесс, 2) будет автоматически bind/unbind
{
"click .selector": "myMethod", //delegate, вешается на htmlinit, снимается на htmldestroy
"scroll .myselector": "myMethod2", //find + bind, вешается на htmlinit, снимается на htmldestroy, delegate делать нельзя - исключение для scroll
"scroll window": "myMethod3", //$(window).on, вешается на show, снимается на hide
"resize window": "myMethod4", //$(window).on, вешается на show, снимается на hide
}
- doochik: дополнение к предыдущему пункту. Надо разделять события, которые надо вешать на hide/show и htmlinit/htmldestroy. Например, scroll или resize надо вешать на hide/show, чтобы они не обрабатывались в скрытых view
- doochik: обработчики у view должны быть событиями. Тогда мы избежим ситуации, когда в одном обработчике что-то делаеют несколько несвязных участов кода. Будет легче тестировать, отлаживать и один обработчик не будет мешать другому.
- lazy-view. view запускаются отдельно после глобального updater. в глобальном updater на их месте можно отрисовать заглушки или какую-то часть информации из закешированных model. Если у lazy-блока все Model есть в кеше, то он отрисовывается нормально, без lazy-вставок. На основе этих блоков в некоторых местах мы делаем красивую анимацию: при переходе в новому экрану мгновенно создается новый блок с крутилкой, меняем css и красиво анимируем показ, потом загружаем данные и делаем нормальную отрисовку.
- view.onprepare - блок может добавить или удалить какие-то параметры для запроса за своими хендлерами. Причем эти измененные параметры не будут влиять на другие view и данные запросятся отдельно
- view.beforeHandlerRequest - штука для управления updater. Оттуда view может вернуть 4 варианта - ok, request_and_return (запросить текущие данные и снова прийти ко мне), not_ready - Мои хендлеры сейчас нельзя запросить, вернуться после очередного запроса, redirect - перейти к другому урлу. Это в каком-то виде реализация дозапроса данных для model
- У нас много тяжёлых запросов к бекенду и поэтому большинство ручек асинхронные. Мы сделали поддержку асинхронных операций на клиенте. Там есть объекты операций, очереди операций, мы заботимся об ограничении количаества запросов и о частоте запросов конкретных ручек (ручек статуса). Может быть мы хотим такую штуку на уровне фреймворка?