Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Collection – фреймворк для управления данными (https://javascript.ru/forum/project/27848-collection-%E2%80%93-frejjmvork-dlya-upravleniya-dannymi.html)

kobezzza 28.10.2012 22:44

Цитата:

Сообщение от melky (Сообщение 212778)
хм ... ну, только сам автор кода знает, как его коду лучше жаться :)

Я могу ужать ещё дето 0.5-1 килобайт, но код поддерживать будет геморней, да и мараться не охота:)

Цитата:

Сообщение от melky (Сообщение 212778)
я его тоже использую. Если можно, расскажете поподробнее о личных допилах ?

Поддержка инклудов в CSS через @import, поддержка инклудов для HTML шаблонов на JS в HTML (шаблон включается в разметку и врапится тегами script), @pref в CSS заменяет свойство, на свойство с вендорными префиксами, @base64-url в CSS идёт по указанному адресу и подставляет DATA:URI, вроде всё:)

tenshi 29.10.2012 02:35

Опа, ещё один велосипед, но какой-то совсем уж уродский)

информация к размышлению: http://hyoo.ru/?article=%D0%9C%D0%BE...author=Nin+Jin

tenshi 29.10.2012 02:43

господи, и тут sql, сделайте меня развидеть это >_< пожалейте тех, кому придётся с вашим кодом работать...

kobezzza 29.10.2012 09:15

Цитата:

Сообщение от tenshi (Сообщение 212803)
Опа, ещё один велосипед, но какой-то совсем уж уродский)

информация к размышлению: http://gist.vrozetke.com/?article=%D...author=Nin+Jin

Спасибо за ссылку, но не понятно к чему она? Данный тред не про систему сборки, а про фреймворк для работы с данными. А если говорить про сборку файлов в Collection, то там на мой взгляд как раз всё прозрачно: зависимости модулей прописаны в модулях, общая схема сборки прописана в core.js, а чтобы редактировать сборку не нужно даже ничего менять, достаточно лишь запустить сборку build.js и указать нужные флаги сборки.

Цитата:

Сообщение от tenshi (Сообщение 212804)
господи, и тут sql, сделайте меня развидеть это >_< пожалейте тех, кому придётся с вашим кодом работать...

Не нравится - не юзай. SQL нужен чтобы повысить уровень абстракции и человеку было проще войти в контекст, к тому же сложный запрос выглядит гораздо более читабельней в SQL, нежели в кучи колбеков или объектов, однако разумеется в первую очередь у меня сделано простое АПИ на колбеках, а SQL я добавил только сейчас, как сахар.

ЗЫ: не пиши плз в этой теме ничего не по делу, уже одну тему засрали в оффтопе.

B~Vladi 29.10.2012 10:51

kobezzza,
судя по этой строке кода и реализации Collection.extend, конструктор Collection в разных ситуациях может возвращать экземпляры с разными наборами свойств. Если это так, то это не круто - GCC будет использовать разные скрытые классы для созданных экземпляров. Может стоит причесать? Особенно актуально для Node.js.

ЗЫ: после статьи на хабре и доклада на конференции стал больше обращать внимание на такие вещи...

kobezzza 29.10.2012 11:05

Цитата:

Сообщение от B~Vladi (Сообщение 212816)
kobezzza,
судя по этой строке кода и реализации Collection.extend, конструктор Collection в разных ситуациях может возвращать экземпляры с разными наборами свойств. Если это так, то это не круто - GCC будет использовать разные скрытые классы для созданных экземпляров. Может стоит причесать? Особенно актуально для Node.js.

Ну да, вторым параметром конструктора может быть объект, который миксится со свойствами по умолчанию, с замечанием согласен, но в данном случае это скорее нормально, чем нет, т.к. свойства микса являются публичными и специально помечены мною, как не сжимаемые.
Данная фича нужна, т.к. момент инициализации скрипта Collection (т.е. выполняется один раз при инициализации <script>) сам генерит себе множество стандартных методов по формуле (что даёт реальный профит при сжатии, но к слову, я сравнивал с GCC при статичном сжатии и мой вариант оказался лучше). Хотя на самом деле, я давно подумаю о выпиливании второго параметра, т.к. на практике оказывается не нужным, т.к. удобнее юзать специальное стековое АПИ, может теперь, после твоего замечания, выпилю :)

https://github.com/kobezzza/Collecti...lds/sys.js#L44
https://github.com/kobezzza/Collecti...ack/aliases.js

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

B~Vladi 29.10.2012 11:23

Цитата:

Сообщение от kobezzza
код должен быть понятным человеку, а потом уже машине

Согласен, но это как раз тот случай, когда обоим хорошо :)

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

kobezzza 29.10.2012 11:33

Цитата:

Сообщение от B~Vladi (Сообщение 212821)
Попробуй протестировать потребление памяти при создании большого количества экземпляров.

На выходных мб заморочусь, хотя сама архитектура спроектирована так, что удобнее и лучше инкапсулировать данные в одном инстансе, через стековое API, т.к. при таком подходе появляется возможность взаимодействия коллекций между собой, например перемещения, джойны и т.д.

Хотя если юзать Collection как простой врапер для коллекций, то мб в этом и есть смысл, аля:
$C([1,2,3,4]).get(function (el) { return el % 2; });

tenshi 29.10.2012 21:30

> Спасибо за ссылку, но не понятно к чему она?

пригодится

> зависимости модулей прописаны в модулях, общая схема сборки прописана в core.js,
> достаточно лишь запустить сборку build.js и указать нужные флаги сборки.

сколько лишних телодвижений..

> Не нравится - не юзай.

я и не юзаю) но ты тратишь своё время впустую

> а SQL я добавил только сейчас, как сахар.

вот именно что, фича для галочки. тонны кода, а как сделать банальное - выбрать записи со значением поля "';DROP TABLE users" я так и не нашёл.

> ЗЫ: не пиши плз в этой теме ничего не по делу, уже одну тему засрали в оффтопе.

засрём и эту :write:

tenshi 29.10.2012 21:40

да, и я смотрю ты активно используешь eval - это крайне медленно. ибо jit приходится каждый раз напрягаться. использование замыканий даёт лучший результат.
вот, смотри, например, низкоуровневый шаблонизатор без единого эвала http://habrahabr.ru/post/99005/

kobezzza 29.10.2012 21:53

Цитата:

Сообщение от tenshi (Сообщение 212906)
я и не юзаю) но ты тратишь своё время впустую

Я так не думаю, либа решает мои проблемы и решает как я хочу, к тому же я пишу её почти столько же, сколько пишу на ЖС и каждая версия тренит мои скилы и знания (в итоге я получаю за свою работу кучу бабла, и могу хоть завтра пойти и купить себе новенький мерседес, чем не профит?) + я тупо получаю от этого кайф.

Цитата:

Сообщение от tenshi (Сообщение 212906)
вот именно что, фича для галочки. тонны кода, а как сделать банальное - выбрать записи со значением поля "';DROP TABLE users" я так и не нашёл.

Интерпретатор весит очень мало, килобайта 4. DROP делать нет смысла, для этого есть специальный метод.
Интепретатор призван заменить цепочки .get().group().stat().sort().get() и т.д. в один простой и очевидный запрос, а для всяких DROP - это просто не нужно.

Цитата:

Сообщение от tenshi (Сообщение 212907)
да, и я смотрю ты активно используешь eval - это крайне медленно. ибо jit приходится каждый раз напрягаться. использование замыканий даёт лучший результат.
вот, смотри, например, низкоуровневый шаблонизатор без единого эвала http://habrahabr.ru/post/99005/

Я юзаю eval в 3-х местах на 7к строк кода - это активно (из них кстати интерпретатор это 15%)? Тем более, что через eval проходит лишь малая часть (80% интерпретатора работает без eval), которая один раз компилится и далее кешируется. Без eval было бы просто тупо больше кода и мне это не нравится, скорость работы от такого приёма падает на 1-2%.

Твои комменты не обоснованы и глупы, а если ты пытаешься троллить, то делаешь это слишком толсто.

B~Vladi 29.10.2012 21:57

Кстати, на счет eval-ов. Еще один аргумент в пользу new Function - V8 применяет внутринние оптимизации для таких функций, а для eval нет. Стоит заменить.

Сори, что ввел в заблуждение в предыдущих постах. Там вместо GCC имелся ввиду V8, конечно же. А я думал, причем тут сжатие)) kobezzza, перечитай тот пост еще раз))

kobezzza 29.10.2012 22:03

Цитата:

Сообщение от B~Vladi (Сообщение 212910)
Кстати, на счет eval-ов. Еще один аргумент в пользу new Function - V8 применяет внутренние оптимизации для таких функций, а для eval нет. Стоит заменить.

Сори, что ввел в заблуждение в предыдущих постах. Там вместо GCC имелся ввиду V8, конечно же. А я думал, причем тут сжатие)) kobezzza, перечитай тот пост еще раз))

Я юзаю new Function где могу, а eval там, где мне нужно создать функцию в контексте другой, а не в глобальном scope. Т.к. в HAVING условиях могут указываться статистические функции, то я оптимизирую это за счёт того, что все указанные в запросе (в любых местах) функции вычисляются все сразу за один проход, а потом просто раздаются по значению, как раз тут мне и удобно (подчёркиваю, удобно) заюзать доступ к родительскому scope.

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

Ок, перечитаю)

B~Vladi 29.10.2012 22:16

Можно прокинуть функции аргемунтами. Хотя тебе виднее :)

kobezzza 29.10.2012 22:21

Цитата:

Сообщение от B~Vladi (Сообщение 212916)
Можно прокинуть функции аргемунтами. Хотя тебе виднее :)

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

devote 29.10.2012 22:22

Цитата:

Сообщение от tenshi
я и не юзаю) но ты тратишь своё время впустую

с чего ты взял? ты думаешь если ты не юзаешь, значит другим тоже не надо? Глупая логика.

tenshi 29.10.2012 22:33

> я тупо

вот тут беда. пишешь код для себя, а суёшь его в проекты, которые разрабатываешь не только ты.

> Интерпретатор весит очень мало, килобайта 4

да всё оно по отдельности мало весит, только вот конечное приложение получается почему-то под мегабайт

> DROP делать нет смысла, для этого есть специальный метод.

http://xkcd.ru/327/

> Я юзаю eval в 3-х местах на 7к строк кода

а если вынести его в функцию myeval, то вообще в одном месте использоваться будет)

> скорость работы от такого приёма падает на 1-2%.

значит что ты ты делал не правильно

> делаешь это слишком толсто

оччёрт, еда меня раскусила ._."

tenshi 29.10.2012 22:36

Цитата:

Сообщение от B~Vladi (Сообщение 212910)
Кстати, на счет eval-ов. Еще один аргумент в пользу new Function

не-не-не, лучше и без new Function обойтись. не за чем поднимать js-интерпретатор несколько раз

B~Vladi 29.10.2012 22:38

Если ТС это интересно, я смотрю на его либу как на дополнение к своему шаблонизатору. Что-то вроде XSL для JS-объектов, который будет использоваться в коде шаблона. Я не имею ввиду нативное встраивание, а как подключение дополнительного инструмента. Если он не будет сильно сказываться на производительности ;)

B~Vladi 29.10.2012 22:43

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

tenshi 29.10.2012 22:43

> на компиляцию запроса нужно больше времени

емнип, в опере это будем "намного больше времени")

> а сам запрос генерится в более эффективный JS код

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

> запросы кешируются тоже

даже запросы с вариативными данными? кэшхиты замерял?)

tenshi 29.10.2012 22:44

Цитата:

Сообщение от devote (Сообщение 212918)
с чего ты взял? ты думаешь если ты не юзаешь, значит другим тоже не надо? Глупая логика.

там у меня стоит союз "но", а не "потому что".

tenshi 29.10.2012 22:49

> Что-то вроде XSL для JS-объектов, который будет использоваться в коде шаблона.

а его можно глянуть?

> задачи бывают разные и во многих ситуациях "поднятие интерпретатора" во много раз увеличивает производительность.

ну для сферической задачи в вакууме бывает и sleep(100) увеличивает производительность) помню был на хабре топик где описывалось как таким образом лечили какую-то проблему с блокировками в многопоточной среде. и это реально помогало.. какое-то время) сейчас уже не найду.

kobezzza 29.10.2012 22:49

Цитата:

Сообщение от tenshi (Сообщение 212921)
> я тупо

вот тут беда. пишешь код для себя, а суёшь его в проекты, которые разрабатываешь не только ты.

> Интерпретатор весит очень мало, килобайта 4

да всё оно по отдельности мало весит, только вот конечное приложение получается почему-то под мегабайт

У либы очень подробная дока и мануал, её очень просто освоить (было бы желание), код либы прочтёт любой хороший специалист.

Весит вся либа 15 килобайт, в версии с одним интепретатором где-то 7, при этом без потери функциональности, где ты нашёл пол мегабайта я не знаю.

В общем tenshi, твои замечания голословны и направлены лишь на троллинг, не знаю как ты как специалист, но работать с таким "умником" я бы точно не хотел, все следующие твои посты я буду тупо игнорить.

kobezzza 29.10.2012 23:09

Цитата:

Сообщение от B~Vladi (Сообщение 212924)
Если ТС это интересно, я смотрю на его либу как на дополнение к своему шаблонизатору. Что-то вроде XSL для JS-объектов, который будет использоваться в коде шаблона. Я не имею ввиду нативное встраивание, а как подключение дополнительного инструмента. Если он не будет сильно сказываться на производительности ;)

Интересно было бы взглянуть и пощупать:) Ну а производительность разумеется я буду улучшать в каждой новой версии.
Пожалуй, я теперь точно последую твоему совету и напишу бенчмарки для Collection, чтобы лучше видеть общую картину.

tenshi 29.10.2012 23:11

> код либы прочтёт любой хороший специалист

любой хороший специалист увидев этот код, сразу его выпилит, ибо его дебаг и реверс инженеринг превращается в сущий кошмар)

> Весит вся либа 15 килобайт

зазипованная, ага. десяток таких "компактных" либ и получаем 150кило несжимаемого трафика, целую секунду на загрузку на мегабите и под сотню миллисекунд на инициализацию.

devote 29.10.2012 23:20

Цитата:

Сообщение от tenshi
десяток таких "компактных" либ и получаем 150кило

сразу видно джукверист, ибо только джукверисты пихают в проект десяток и более всяких говноплагинов для джуквери

Gozar 30.10.2012 00:46

Цитата:

Сообщение от devote
пихают в проект десяток и более

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

kobezzza,
Внимательно слежу. Поюзаю в свободное время, если оно у меня будет.

tenshi,
читаю твою критику как роман. Даже просыпаюсь в этот момент.

ps: девочки не деритесь, вы обе приятные на ощупь. ;)

DjDiablo 30.10.2012 01:58

kobezzza

слушай а где документация по событиям ?
решил потыкать и упёрся в отсутствие инфы по событиям
Вроде как есть в исходниках, но негде не описано.

если я правильно понял то только один метод можно повесить на onSort, если да то печально :(


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

devote 30.10.2012 03:50

Цитата:

Сообщение от Gozar
сколько ты уверенно утверждаешь что он не прав.

за всю свою карьеру программиста, не подключал скриптов более 100кб на проект. Я понятия не имею что там нужно на подключать или что за проект должен быть что бы юзать такое огромное количество скриптов. Но скажу уверенно, джукверисты умудряются это делать даже на проектах вида сайт-визитка... Подобное видовал не раз.

kobezzza 30.10.2012 09:23

Цитата:

Сообщение от DjDiablo (Сообщение 212963)
kobezzza

слушай а где документация по событиям ?
решил потыкать и упёрся в отсутствие инфы по событиям
Вроде как есть в исходниках, но негде не описано.

если я правильно понял то только один метод можно повесить на onSort, если да то печально :(


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

1) http://www.collection-js.com/manual/part-9.html - предпоследний параграф. Свойство принимает те же параметры, что и вызвавший его метод, return false отменяет действие. Да можно повесить только одно событие, но это легко исправить добавив реализацию обсёрвера, могу добавить из коробки если нужно.

2) Список транзакций? Я просто не успел это добавить, будет в версии 3.8.5 на этой недели уже наверно)

B~Vladi 30.10.2012 09:38

Цитата:

Сообщение от tenshi
а его можно глянуть?

Кого?

Цитата:

Сообщение от tenshi
ну для сферической задачи в вакууме бывает

Я имел ввиду конкретные, а не вакуумные.

Цитата:

Сообщение от kobezzza
Интересно было бы взглянуть и пощупать

Ну пощупать пока не удастся, но код накидать могу, что бы было более понятно.

kobezzza 30.10.2012 09:44

Цитата:

Сообщение от B~Vladi (Сообщение 212987)
Ну пощупать пока не удастся, но код накидать могу, что бы было более понятно.

Было бы здорово.

B~Vladi 30.10.2012 12:48

Цитата:

Сообщение от kobezzza
Было бы здорово.

Вообще, идея намного шире. Речь об области применения этой либы. Конкретно - в шаблонизаторах.

Данные, скармливаемые в шаблон при рендеринге, могут быть либо view-ориентированными, либо data-ориентированными.

View-ориентированные сложно подготавливать. На каждый конкретный случай приходится писать много view-логики, которую хочется перенести в шаблон. С такими данными работает dust и ему подобные.

С data-ориентированными данными справится не каждый шаблонизатор, либо придется писать кучу проверок в виде конструкций шаблона. Но такие данные проще подготовить программисту, а уже всякие сортировки/группировки делать в шаблоне. Вот как раз в этом случае Collection.js может сделать эту работу лучше, чем "куча проверок в виде конструкций шаблона".

Есть несколько шаблонизаторов, которые позволяют писать JavaScript-выражения для доступа к данным. Например, для получения массива, что бы затем его скормить циклу. Приведу пример для своего шаблонизатора.

var TEN = require('TEN');
var Collection = require('Collection');

var data = [
	{name: 'Andrey', sex: 'male', age: 22},
	{name: 'Sergey', sex: 'male', age: 24},
	{name: 'Ann', sex: 'female', age: 18},
	{name: 'Kate', sex: 'female', age: 21},
	{name: 'Vera', sex: 'female', age: 15},
	{name: 'John', sex: 'male', age: 28},
	{name: 'Paul', sex: 'male', age: 32}
]; // Тут мы сформировали какие-то данные для шаблона, взял из документации

TEN.render('index.xml', new Collection(data));


Ну а в самом шаблоне используем API Collection:

<?xml version="1.0" encoding="UTF-8"?>
<ten:root xmlns:ten="TEN" xmlns="http://www.w3.org/1999/xhtml">
  <!-- Делаем необходимую выборку, так же взято из доки -->
  <ten:each array="this.sort('age').remove(':el.sex == &quot;female&quot; && el.age < 18')" item="user">
    <!-- Выведутся имена совершеннолетних пользователей, отсортированные по возрасту. -->
    <ten:echo data="user.name" />
  </ten:each>
</ten:root>


По-моему выглядит неплохо, не пришлось писать if-ы внутри цикла. Конечно, фильтрация может быть намного сложнее (как показывает практика работы с XSL), и профита будет больше.

Здесь, по-сути, Collection играет роль фильтра, как в Smarty, но намного мощнее.

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

Что думаешь?

kobezzza 30.10.2012 14:05

Цитата:

Сообщение от B~Vladi (Сообщение 213013)
Что думаешь?

Идея интересная, ты юзаешь Collection внутри шаблона для выборок, тем самым шаблон получается простым и мощным, но да, нужно очень оптимизировать работу (я углублюсь в этом вопросе).

Я как то от таком подходе даже не думал, и когда реализовал поддержку шаблонов в самом Collection исходил из логики: сначала данные готовятся, потом показываются (т.е. 2 прохода), а тут можно сделать в один.

B~Vladi 30.10.2012 14:12

Цитата:

Сообщение от kobezzza
ты юзаешь Collection внутри шаблона для выборок

Тот же принцип реализован в Yate, но со своим блекджеком. Такой инструмент очень полезен в шаблонах.

DjDiablo 30.10.2012 15:26

koobezzzza - нет не транзакциии :)

Я говорю о взаимодействии с сервером.
допустим хотим написать грид с возможностью удаления, редактирывания, и создания записей, все изменения сохраняются по кнопки save.

возьмём 4 типовых операций для взаимодействия, СRUD
create - создание новых записей
read - чтение записей
update- обновление записей
delete - удаление записей.

допустим пользователь понасоздавал, редактирывал и удалял записи
а теперь нажал save

я должен вызвать 3 серверных комманды.
1) выбрать из твоей базы все вновь созданные пользователем записи, эту инфу отправим допусти на www.myapp.ru/test/create.php
2) выбрать из твоей базы все записи которые пользователь редактирывал хоть однажды, и бередать их команде www.myapp.ru/test/update.php. Надеюсь ясно что те которые пользователь нередактирывал передавать нет необходимости
3) выбрать все те записи которые пользователь удалил и передать их на сеbрвер допустим в www.myapp.ru/test/delete.php.

впрочем можно упростить взаимодействие с сервом и свести всё к двум командам load и save
для save придётся отправить файл вида
{
   create:[],//список записей подлежащих созданию
   update:[],//список записей подлежащих обновлению
   delete:[]//список полей подлежащих удалению
}

тоесть в твоей либе должно быть что-то вроде метода getCRUD который вернёт {create:[], update:[], delete:[] }
для простоты примера будем считать что в бд будет что то вроде
[
    {id:1,name:"lala"},
    {id:2,name:"lala"}
]


ЭТО МОЁ 666е СООБЩЕНИЕ )))

kobezzza 30.10.2012 15:50

DjDiablo ну как вариант можно на каждое действия пользователя слать запрос, но ето не тру:)

Твою идею я понял, действительно нужная штука, так что добавлю.

Цитата:

ЭТО МОЁ 666е СООБЩЕНИЕ )))
Поздравляю :)

tenshi 31.10.2012 01:27

> твои посты я буду тупо игнорить

слив засчитан

> сразу видно джукверист, ибо только джукверисты пихают в проект десяток и более всяких говноплагинов для джуквери

не угадал

> В зависимости от проектов приходиться делать не только приятные глазу вещи.

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

> если я правильно понял то только один метод можно повесить на onSort, если да то печально

вешаем на onSort какой-нибудь EventRouter и проблема решена)

> Я понятия не имею что там нужно на подключать или что за проект должен быть что бы юзать такое огромное количество скриптов.

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

tenshi 31.10.2012 02:26

B~Vladi, смешивать трансформацию модели (из дата ориентированной во вью ориентированную) и шаблонизацию - плохая идея.
фактически не данные нужно преобразовывать в хтмл, а нужно создать модель представления, которая:
1) выберет из базы то, что ей нужно (это может быть выборка как из Collection, json, xml так и запрос к серверу, если данных дофига)
2) отрендерит себя в json/html/dom или куда там ещё надо

смешивать эти два процесса - это классно лишь на простеньких демо-примерах.

вот что ты будешь делать, когда потребуется рядом со списком совершеннолетних пользователей вывести рядом список несовершеннолетних? у тебя будет 2 шаблона отличающихся лишь запросами данных (привет, копипаста). будет 2 отдельные выборки из базы (привет, тормоза). в то время как логика подсказывает, что эффективней было бы один раз пройтись по массиву, раскидав записи по двум одинаковым моделям и отрендерить их одним же шаблоном.


Часовой пояс GMT +3, время: 06:46.