JBlocks — небольшой jQuery-плагин (~100 строк) для организации компонентов на странице.
Строится на трех основных принципах:
Если вам интересна тема декларативного javascript — прошу под кат.
Пусть у нас есть простой контрол: счетчик. Шаг счетчика — параметр, который можно менять для разных экземпляров.
Демо
Объявим новый компонент counter:
Разметим в html компонент с помощью специальных атрибутов:
Компоненты можно инициализировать с помощью $.fn.jblocks('init') и уничтожать с помощью $.fn.jblocks('destroy'):
С помощью функции $.fn.jblocks('get') можно получать ссылки на экземпляры. Если компонент еще не был инициализирован, то сперва это будет сделано.
UPD:
Спасибо всем за конструктивную критику (и даже один пул реквест). Обновил репозиторий и описание статьи в соответствии с новым АПИ.
Строится на трех основных принципах:
- опиши поведение компонента в декларации;
- разметь компонент в html с помощью специальных атрибутов;
- общайся со экземплярами компонента через АПИ.
Если вам интересна тема декларативного javascript — прошу под кат.
Пусть у нас есть простой контрол: счетчик. Шаг счетчика — параметр, который можно менять для разных экземпляров.
Демо
Объявим новый компонент counter:
$.jblocks({
// имя компонента
name: 'counter',
// декларация событий
events: {
// встроенные события: b-inited, b-destroyed
'b-inited': 'oninit',
// дом-события
'click .js-inc': 'onClickPlus',
'click .js-dec': 'onClickMinus'
},
// методы компонента
methods: {
oninit: function() {
this.$info = this.$node.find('.js-info');
this.count = 0;
},
/**
* Обработчик клика на плюс
*/
onClickPlus: function() {
this.inc();
this.update();
},
/**
* Обработчик клика на минус
*/
onClickMinus: function() {
this.dec();
this.update();
},
/**
* Увеличить счетчик
*/
inc: function() {
this.count += this.params.step;
},
/**
* Уменьшить счетчик
*/
dec: function() {
this.count -= this.params.step;
},
/**
* Нарисовать новое значение
*/
update: function() {
this.$info.text(this.count);
}
}
});
Разметим в html компонент с помощью специальных атрибутов:
<div class="foo" data-b="сounter" data-p='{ "step": 2 }'>
...
</div>
- data-b — айдишник блока (имя)
- data-p — параметры блока
Компоненты можно инициализировать с помощью $.fn.jblocks('init') и уничтожать с помощью $.fn.jblocks('destroy'):
// Инициализируем все блоки в документе
$(document).jblocks('init');
// Уничтожаем все блоки в документе
$(document).jblocks('destroy');
// Или внутри конретной части DOM-дерева
$('#app').jblocks('init');
С помощью функции $.fn.jblocks('get') можно получать ссылки на экземпляры. Если компонент еще не был инициализирован, то сперва это будет сделано.
$('.foo').jblocks('get').each(function() {
// this - экземпляр блока, inc — его метод
this.inc();
});
UPD:
Спасибо всем за конструктивную критику (и даже один пул реквест). Обновил репозиторий и описание статьи в соответствии с новым АПИ.
Delphinum
Не так давно написал подобное, назвал это виджетами и активно пользую. В общем то логика «блоков» очень проста, проблемы появляются уже при решении прикладных задач.
vitkarpov
Да, действительно, виджеты — это оно же. Спасибо.
Решил поделиться решением, вдруг кому-то будет полезно: кажется, каждый пишет нечто подобное, если не пользуется чем-то более тяжелым.
Delphinum
Ну собсна решение сводится к следующему:
vitkarpov
Спасибо. Да, действительно, это все интересные задачки.
Borz
про заголовок статьи подумалось: «фреймворк на фреймворке и фреймворком погоняет»
это же чистой воды плагин в терминологии jQuery
по содержимому статьи — хотелось бы ещё увидеть пример отправки события на сервер.
vitkarpov
Да, действительно, похоже на то. Спасибо.
JBlocks всего лишь способ описать виджеты на странице. Если нужно делать запрос на сервере: можно завести метод fetch, который дернет $.ajax внутри. Далее все зависит от логики приложения: можно найти блок на странице с помощью getBlocks и вызвать метод fetch когда это будет необходимо.
Borz
думается, более правильным было бы при вызове метода initBlocks() в качестве опционального аргумента принимать callback-функцию, вызываемую при изменении счетчика
Ashot
Вот такое решение кажется сомнительным.
Во-первых, слово define очень уж общее, и не понятно, что определяется именно JBlock.
Во-вторых, использовать такое «общее» слово в качестве имени метода в корне объекта jQuery может привести к казусам, если в разработчик другого плагина тоже решит определить свой $.define. В общем, я бы на вашем месте переименовал бы метод в defineJBlock — и более точно определяет, что метод делает, и вряд ли его кто-нибудь перекроет.
Я могу и ошибаться в своём мнении, но мне кажется так будет безопасней.
vitkarpov
Да, действительно. Пространство имено — очень важно. Просто хотелось сделать название как можно более очевидным. Видимо, лучше сделать $.jbDefine. Спасибо!
newkamikaze
Добавьте коллбэк после изменения значения, чтобы можно было использовать ajax.
vitkarpov
Если я правильно вас понял, то логику отправки нового значения на сервер, после изменения значения счетчика, можно либо инкапсулировать в блоке:
либо, т.к. в данном случае метод inc синхронный, можно вызвать где-то в коде приложения сперва inc у блока, а затем updateOnServer
Delphinum
Почему бы просто не выбрасывать событие, информирующее об изменении состояния (возможно конкретного параметра) блока? На это событие можно будет декларативно подписать внутренний или внешний метод и в нем отсылать сообщения на сервер.
vitkarpov
Да, можно и так действительно.
GIum
Какой же это нано-фреймворк если он зависиом от jQuery? Да и какой вообще смысл от jQuery в 2015 кроме как поддержка старых версий IE?
withoutuniverse
Не подумайте, что я придираюсь, мне правда интересно (я понемногу изучаю верстку и программирование для веб):
Какие сегодня есть альтернативы jQuery? Почему он считается устаревшим?
Если не использовать jQuery, то не выйдет использовать и тот же Bootstrap, а какие ему сегодня есть популярные альтернативы?
GIum
Он не столько устарел, сколько просто потерял свою необходимость по мере развития браузеров. Смотрите VanillaJS в качестве альтернативы.
По поводу бустрапа, не все так печально, Вы просто не сможете использовать его плагины, а это далеко не самая его важная часть. Да и есть энтузиасты которые портировали его на ту же ванилу.
withoutuniverse
Я немного не понял — вы троллите? Предлагаете написать 240 килобайт jQuery кода на велосипеды в виде чистого javascript?
Есть ли реальные альтернативы jQuery? Есть ли реальные альтернативы Bootstrap?
GIum
Нисколько.
Зачем тебе писать свой jQuery?
withoutuniverse
Предпочту общаться на ВЫ.
Мне понадобится как минимум около 30 методов, реализация которых уже имеется в jQuery.
Не вижу смысла изобретать велосипед заново и писать кроссплатформенный код, если подобное уже сделано профессионалами.
Вы так и не ответили на мой вопрос: Есть ли реальные альтернативы jQuery? Есть ли реальные альтернативы Bootstrap?
GIum
Смотри выше.
symbix
Реальная альтернатива бутстрапу — бутстрап.
Какой такой кроссплатформенный код? Вам нужна поддержка IE6? Современный JavaScript (ES5+) ничем не менее удобен, чем jquery, если же нужна поддержка IE8 — есть ES5-shim.
dom1n1k
Идея хорошая (что-то типа очень лайтового Backbone), но апи надо переписывать и убирать всё из глобальной области видимости.
Первый блин комом, но судя по аккуратному и симпатичному в целом коду, автору не составит труда довести до ума блин номер два.
vitkarpov
Предлагаете отказываться от jQuery как зависимости и поддержать нормальную модульность?
Изначальная идея была в том, чтобы сделать штуку для, грубо говоря, простого верстальщика, который привык работать с jQuery и на простом сайте он уже подключен.
dom1n1k
Нет.
По идеологии jQ-плагинов, они не должны совать свои методы в глобальный объект $. Тем более, с такими общими и неуникальными именами, как initBlocks или destroyBlocks.
Обычно принято делать примерно так:
Это убирает весь функционал плагина в одно пространство имён и позволяет сохранить цепные вызовы, если нужно.
novoxudonoser
Присоединяюсь, почистите апи и добавьте местные советы, получится отличный легковесный плагн.
jrip
Ок, круто. Вы придумали чутка недоделанный Backbone.
backbonejs.org
vitkarpov
Бэкбон это все-таки про одностраничные приложения, а это скорее reactjs, только очень простой — не для веб-приложений, которые живут годами, а для простых сайтов, например, лендингов
jrip
View из бекбона можно использовать и на многостраничных приложениях, будет ровно тоже самое что у автора этого фреймворка.
Вот это, как раз View бекбона, даже events там такие же:
$.define('сounter', {
// декларация событий
events: {
// встроенные событие блока: b-inited, b-destroyed
'b-inited': 'oninit',
// дом-события
'click .js-inc': 'onClickPlus',
'click .js-dec': 'onClickMinus'
},
// методы блока
methods: {
}
}
InteractiveTechnology
Сделали на backbonejs несколько сложных UI корпоративных систем в стиле extjs. Так что вы чего-то наговариваете лишнего, один из удобнейших фреймворков. Всего лишь backbonejs+requirejs и вот вам готовая модульная система с неограниченными возможностями построения клиентской части :)
Delphinum
Вы ошибаетесь. Хотите приведу пример того, что эта связка не может? )
InteractiveTechnology
Конечно, если не сложно, с радостью!
Delphinum
Недавно была такая проблема. Есть у нас каталог виджетов, в котором каждый виджет хранится в отдельном файле. При открытии страницы на ней с помощью JS мы находим все узлы с data-widget="..." и используем их как корни для соответствующих виджетов. Тобишь:
долже быть использован как корень для виджета public/scripts/widgets/Select.js и т.д.
Дело тут в том, что виджеты должны загружаться и подключаться к странице синхронно. После загрузки и подключения всех виджетов JS должен отсигналить об этом событием. Как это сделать, если учесть, что requirejs не хочет синхронно?
vitkarpov
А не хочется собрать весь js виджетов в один бандл и загрузить на страницу целиком?
Delphinum
Нельзя, начальство против.
vitkarpov
Может стоит глянуть в сторону YM-модулей, вроде есть поддержка асинхронности.
Delphinum
Нужна поддержка синхронности )
InteractiveTechnology
Разве так не работает?
Можно вот такой хак, вместо requirejs
Delphinum
Предполагается что будет так:
но это нисколько не синхронно.
Мы же с вами о связке, а не о хаках говорим ;)
InteractiveTechnology
Так
Delphinum
Ок, а как вызвать в таком случае метод render у виджета? И где здесь синхронность?
zxcabs
webpack -> require.ensure(['./file.js'], function () {}) или require('bundle?lazy!./file.js')(function () {});
Delphinum
Вам бы сначала ветку прочесть, а уже потом webpack'и предлагать ;) (не в обиду)
У webpack, кстати, тоже есть одна нерешаемая проблема.
zxcabs
какая?
Delphinum
Я уже упоминал о ней на хабре, но мне не удалось толково объяснить задачу.
Если коротко, нужно заставить webpack в зависимости от прикладной логики собирать проект с подключением и без подкбючения модуля.
stas404
Это случайно не то, что вы имеете ввиду?
DefinePlugin:
https://webpack.github.io/docs/list-of-plugins.html#defineplugin
Resolve:
https://webpack.github.io/docs/configuration.html#resolve-alias
Delphinum
Может быть, но все усложняется еще тем, что в результирующем js файле не должно быть ничего, с помощью чего пользователь сможет открыть исходник, который ему не предназначался. То есть на пример у нас есть admin.js, этот файл должен подключаться для админов, но для обычных пользователей его не просто нужно заменить на заглушку, но и вообще не включать при сборке. Ну и, естесна, делать две сборки, с admin.js файлом и без него нельзя.
stas404
Если в результирующем js-файле (давайте назовем его index.js) не хочется упоминаний и намеков на admin.js, то можно, например, сделать две «entry points»:
При этом на выходе получим два отдельных файла — обычному пользователю отдаем один index.js, админу оба: index.js + admin.js.Delphinum
stas404
Да, только под «двумя сборками» я понял два разных бандла (отдельный бандл для пользователя и отдельный для админа) и грузится либо один, либо другой.
А тут у вся общая логика лежит в index.js, а в admin.js лишь то, что относится к админу и отдается сверху тогда, когда необходимо.
Ответьте на три вопроса, подумаем вместе.
1) Чем не устраивает подход?
2) В каком виде вы представляете и хотели бы получить результат, с учетом того, что «в результирующем js-файле не должно быть ничего, с помощью чего пользователь сможет открыть исходник, который ему не предназначался»?
3) Решает ли какой-либо существующий сборщик модулей эту задачу более приятным способом?
Delphinum
Да, это и нужно. Возможно я не понял что дает предложенное вами решение.
1) Последний? Ну если он создает то, что вы описали, то вполне устраивает.
2) Два файла с разной логикой.
3) Не знаю, что вы понимаете под приятностью, но когда то я эту зачаду решил через Grunt.
Предлагаю закончить эту тему, а то меня сейчас адепты webpack линчуют )))
oledje
Что-то я не совсем понимаю, что вы имеете ввиду под словом синхронно. Если имеется ввиду последовательная загрузка файлов, то у меня два вопроса:
Для чего загружать файлы последовательно и почему вы решили что RequireJs этого не умеет? RequireJs это просто загрузчик файлов (модулей). Как хотите, так и загружайте. Хоть последовательно (синхронно), поть параллельно (асинхронно).
Delphinum
Ну задача такая.
Потому что пытался заставить его сделать это и наткнулся на то, что RequireJs считает такой подход неправильным и не дает грузить модули синхронно. Если я ошибаюсь, приведите пример синхронной загрузки модуля с помощью RequireJs, буду благодарен.
oledje
Если я правильно понял задачу, то это можно сделать например так:
plnkr.co/edit/6OQlGJVY04FDVn6Q1ABu?p=preview
Во вкладке Network можно убедиться что файлы загружаются последовательно один за другим:
Delphinum
Да так и делаем. Задача в том, чтобы не использовать подобные ухищрения для обхода невозможности синхронной загрузки в RequireJS. Ведь было бы куда проще сделать просто:
Но приходится изощрятся.
Не новая, очень даже старая методология.
oledje
Ну выше вы утверждали что это невозможно, а на деле выходит что это решается в пять строчек кода.
Да, над изощренными задачами всегда приходится изощряться. И я полагаю, что если этот подход обусловлен только тем, что начальство против, то это трижды плохой подход. Нужно уметь аргументировать свою точку зрения, указать начальству на недостатки и предложить альтернативу. Я когда-то уволился только по причине таких задач от начальства компании заказчика.
Delphinum
На деле не решается. Помнится делали мы так, как предлагаете вы, но в результате в файле index.js все же хранится адрес, по которому можно найти admin.js файл. Потому и решили отказаться от использования webpack.
Это все конечно прекрасно, но иногда начальство против и точка. Да, я тоже уволился ))
oledje
Вы наверное что-то путаете. Я не предлагал вам использовать webpack. Изучите внимательно мой пример.
Delphinum
Оу, сорри, попутал ветку )
Ну не совсем решается, на деле это костыль, с помощью которого можно обойти ограничения RequireJS по загрузки модулей синхронно.
oledje
Почему не совсем? Это реализация поставленной вам задачи. Сама по себе задача позразумавает костыльное решение и RequireJs тут не при чем. Никаких ограничений такого рода в RequireJs нет. Где в вебе вообще есть синхронная загрузка файлов? Браузеры по умалчанию загружают файлы асинхронно.
Delphinum
То есть в невозможности синхронной загрузки файла через RequireJS виновата задача?
Как это нет? RequireJS не грузит файлы синхронно.
Берите и грузите файлы синхронно.
oledje
Повторюсь, изучите внимательно мой пример. В нем файлы загружаются синхронно при помощи RequireJs.
Использование jQuery.ajax ни чем не лучше RequireJs, а тем более с параметром async: false.
Во-первых, в вашем случае вам придется городить приблизительно что-то подобное что и в моем примере, вызывая jQuery.ajax в цикле, только выйдет это более громоздко.
Во-вторых, не забывайте, что выполнение таких запросов может временно заблокировать браузер до тех пор пока они не будут выполнены.
В-третьих, имейте в виду, что при загрузке js файлов при помощи jQuery.ajax (с параметром dataType: 'script') или при помощи jQuery.getScript в случае ошибки в загруженном файле вы не получите полезной информации в консоли (такой как файл, в котором произошла ошибка, строка и т.д.).
В-четвертых, использование async: false теперь deprecated при некоторых обстоятельствах.
Delphinum
В вашем примере файлы загружаются синхронно благодаря костылю. Сам RequireJS не грузит их синхронно, нет у него такой функции.
Вопрос не в лучше/хуже, вопрос очень конкретный — загрузка модулей синхронно. Вы говорите что грузить их синхронно нельзя в принципе, я вам привожу пример того, как это легко осуществляется. В RequireJS от такого подхода отказались полностью — только асинхронная загрузка.
Почему же громоздко:
Куда проще вашего примера, так как нет никакой синхронизации потоков.
Может, но мы не об этом.
Так вопрос не в этом, я о том, что RequireJS грузит только асинхронно. Вы можете костылить вокруг этого факта и добится синхронной загрузки, возможно даже лучше чем с помощью $.ajax, но это не отменяет невозможности синхронной загрузки через RequireJS.
Да пактически всегда, видимо от того RequireJS решили и отказаться от синхронной загрузки.
saggid
Ребята, посмотрите на Riot.js) У подобного «бакбоновского» подхода к написанию компонентов есть несколько существенных проблем, и тогда, когда кода, написанного в таком стиле, у вас накопится много, поддержка подобных компонентов усложнится по таким причинам, как:
1. Разделённость представления (html) и логики (js) по разным файлам, из-за чего вы постоянно будете видеть только один фрагмент своего компонента; а также постоянно держать в голове то, как они взаимодействуют друг с другом;
2. Когда у вашего компонента накопится штук 10 event lievener'ов, особенно спустя пол года после его написания, вы долго будете «прощупывать своего слона» в стремлении понять, что там на что навешивается, и как оно вообще работает. Из этого следует также трудность дальнейшего развития подобных компонентов, даже их внешний вид постоянно приходится прорабатывать с учётом того самого массива event listener'ов: удалили какой-то класс у одного из div-ок? А вы уверены, что на него не был навешан event listener какой-нить?) В общем, придётся знать их наизусть и постоянно учитывать при разработке. Я лично работал в подобном стиле, не знаю как вам, но меня это реально удручало и раздражало.
3. У такого подхода нет простой возможности каким-либо образом отрендерить всё это дело на сервере; я лично писал два шаблона: для сервера и для JS. Что тоже часто удручало.
И эти проблемы разрешаются с помощью маленькой UI-библиотеки Riot.js. Весь код компонента в ней можно сложить в одном файле; и самое главное: вместо «бакбоновского» массива со списком слушателей событий, вы просто пишете на нужных элементах атрибуты «onclick», «onmouseover», «oninput», и так далее: Riot.js всё это проанализирует и навесит всё что надо и куда надо. Больше никакой мороки с анализом массива прослушивателей. Сначала это может выглядеть довольно странно, но такой подход на самом деле намного удобнее бакбоновского. При этом, кстати, никто не запрещает навесить какие-то свои дополнительные прослушиватели событий при инициализации компонента, через jQuery.on(), к примеру.
Вот пример того же самого компонента «счетчика» (см. файл counter.html) на основе Riot: http://plnkr.co/edit/hIDIv6fKi4SLUHXleg0U?p=preview. Всего 28 строк кода, причём они содержат сразу и вёрстку, и JS логику, и даже внешний вид вашего виджета. А JS-код компонента вовсе состоит всего из четырёх простых строчек.
Если всё это еще и на основе Jade шаблонизатора писать — то там вообще выйдет очень чистый и приятный для восприятия компонент. Единственное, стили я всё-таки обычно кладу в отдельный scss-файл, так как их зачастую бывает слишком много, и не удобно их хранить в Riot-компонентах по многим причинам, так как теряется возможность их дальнейшей обработки всякими Grunt'ами, а также теряется возможность запихнуть этот кусок стилей в один общий файл app.css. Поэтому, стили я держу отдельно.
Плюс, ко всему прочему, вдобавок вы получаете возможность очень легко рендерить состояние ваших компонентов со стороны сервера через Node.js. К слову, я в своём проекте сделал небольшой сервер на ноде, который создаёт файл unix socket'а в папке проекта и возвращает результат рендера Riot.js компонентов на входящие запросы. А на стороне Пыхчанского я после этого реализовал небольшую функцию, которая коннектится к этому самому сокету и запрашивает нужные компоненты с данными. Итого, я избавил свой проект от написания шаблонов на стороне сервера и полностью переложил всю эту работу на Riot.js. Сначала компоненты сайта рендерит нода; а уже после этого браузер загружает тот же самый код и инициализирует всю JS-логику.
В общем, подобный подход разработки получился намного удобнее и приятнее, чем бакбоновский, которым я тоже ранее пользовался. Рекомендую попробовать работать подобным образом и вам тоже, конечно же.
P.S. Я знаю, что на хабре часто любят задавать разные «провокационные» вопросы, стремясь поумничать, поважничать и унизить слова другого человека. Не обижайтесь, если я оставлю подобное ваше сообщение без своего ответа, так как не люблю пустые разговоры. Не понравился данный подход — я рад за вас, и перетягивать кого-то куда-то насильно я не собирался, я лишь делюсь знаниями с другими ремесленниками. В моём случае это прекрасно работает. Как работать вам — это уже ваше личное решение.
vitkarpov
Хороший подход. По сути, это веб-компоненты, верно?
Delphinum
Мы как бы пытаемся отделить верстку от лигики, а вы предлагаете не только аттрибуты левые использовать, но и собственные теги придумывать? Как то не очень если честно.
Не считаю ни одну из перечисленных вами проблем реальной, все они прекрасно решаются при использовании виджетов.
jrip
>Разделённость представления (html) и логики (js) по разным файлам,
Т.е. по вашему шаблонизаторы это зло?
>из-за чего вы постоянно будете видеть только один фрагмент своего компонента
Может проще купить второй монитор чем все в кучу перемешивать?
> Когда у вашего компонента накопится штук 10 event lievener'ов, особенно спустя пол года после его написания
Если он нужны, они в любом подходе добавятся.
>вы долго будете «прощупывать своего слона»
в «бекбоновском» подходе есть такое понятие как subview
>удалили какой-то класс у одного из div-ок?
Нафига удалять классы из дивов? Надо разделять классы отображения и классы для Js
> У такого подхода нет простой возможности каким-либо образом отрендерить всё это дело на сервере
Реально ли часто, внезапно возникает необходимость что-то отрендерить на сервере? А если и возникает, не проблемы ли это планирования?
>вы просто пишете на нужных элементах атрибуты «onclick», «onmouseover», «oninput», и так далее:
Это здорово, когда интерфейс в целом простой и нет необходимости менять события по ходу работы скрипта.
Ток одного не пойму — нафига при этом использовать этот олдскульный подход, вместо внятного списка селекторов мы получаем лапшеверстку, где вообще фиг поймешь кто куда навешен, пока всю не просмотришь.
>При этом, кстати, никто не запрещает навесить какие-то свои дополнительные
>прослушиватели событий при инициализации компонента, через
Ок, того подхода не хватило, разбавим его еще одним. Главное чтобы тот кто после нас будет дорабатывать не оказался злобным маньяком.
>К слову, я в своём проекте сделал небольшой сервер на ноде, который создаёт файл unix socket'а в папке проекта и возвращает результат рендера Riot.js компонентов на входящие запросы. А на стороне Пыхчанского я после этого реализовал небольшую функцию, которая коннектится к этому самому сокету и запрашивает нужные компоненты с данными. Итого, я избавил свой проект от написания шаблонов на стороне сервера и полностью переложил всю эту работу на Riot.js. Сначала компоненты сайта рендерит нода; а уже после этого браузер загружает тот же самый код и инициализирует всю JS-логику.
Ну и нафига? Не проще отдавать просто данные, например на Пхп, а на клиенте все рендерить?
>Не понравился данный подход — я рад за вас, и перетягивать
>кого-то куда-то насильно я не собирался, я лишь делюсь знаниями с другими ремесленниками.
В том то и проблема, таких «ремесленников» на JS все больше и больше, он уже ПХП переплюнул.
saggid
Дорогой мой собрат по ремеслу) Я же написал: не нравится подход — делайте так, как лично вам нравится.
И советую вам задуматься: чем наполнено ваше сердце? Безосновательной ненавистью к окружающим, высокомерным отношением к работам других людей… Желанием непременно возвыситься на унижении другого человека.
И вы от всего этого удовольствие получаете? Я непричастен к подобным ценностям и занятиям, до свидания.
jrip
>Дорогой мой собрат по ремеслу) Я же написал: не нравится подход — делайте так, как лично вам нравится.
>И советую вам задуматься: чем наполнено ваше сердце?
Мое сердце при прочтении вашего комментария наполнено предчувствием, что есть очень большая вероятность, в дальнейшем, работать с кодом, который написали следуя таким рекомендациями как ваша. Поэтому, чувствую необходимость выразить с вашим комментарием несогласие, дабы вселить в остальных прочитавших некоторое недоверие, а возможно и критическое восприятие.
saggid
Вы просто почти ничего не поняли из того, что я написал в своём самом первом комментарии. Вы не поняли, зачем я так делаю, почему я выбрал именно эту библиотеку, по какой причине я добавил серверный рендеринг к обычному браузерному, по какой причине я отказываюсь от event listener'ов, и так далее… Хотя даже мой коммент довольно подробно всё разъясняет.
Если вы не понимаете чьих-то мотивов, это еще не означает, что вы умнее этого человека, а человек этот обязательно не прав.
Большинство вопросов, которые здесь задают в комментах разные хабровчане — просто из-за их личного невежества. Зачем делать серверный рендер? Зачем кастомные тэги и атрибуты добавлять?.. Такое ощущение, будто весь рунет до сих пор всё судит на основе стандартов прошлого века. О веб-компонентах вообще походу никто ничего не слышал. Мир меняется, развивается, изобретаются новые подходы к разработке, а на хабрахабр народ всё вы***ся и вы***ся в комментариях своими познаниями прошлого десятилетия… Вы еще ждёте, что я буду сидеть тут и вести с вами эти беседы, доказывать вам свою правоту? Зачем мне это? Тем более когда тебе пишут в такой категоричной и высокомерной форме.
Поизучайте современные UI библиотеки на досуге. Не одним Бакбоном же мир живёт. Почитайте о том, зачем нужен серверный рендер, если не понимаете, зачем его делают. Не торопитесь быстрее бежать в комментарии опровергать и предостерегать всех вокруг. Возможно, предостерегать надо от вас, а не от меня. До свидания ещё раз, и всего хорошего вам.
jrip
>Вы просто почти ничего не поняли из того, что я написал в своём самом первом комментарии.
У вас были утверждения, у меня конкретные вопросы к ним, а также конкретные их опровержения.
>Хотя даже мой коммент довольно подробно всё разъясняет.
Нет.
>Если вы не понимаете чьих-то мотивов, это еще не означает, что вы умнее этого человека, а человек этот обязательно не прав.
Умом не меряюсь, ваши утвержения посчитал не правильными, ничего личного.
>Поизучайте современные UI библиотеки на досуге. Не одним Бакбоном же мир живёт.
С чего вы взяли что я не изучал ничего другого и использую только бекбон?
>Большинство вопросов, которые здесь задают в комментах разные хабровчане — просто из-за их личного невежества.
И вы еще пишете про чьето высокомерие?
>Мир меняется, развивается, изобретаются новые подходы к разработке
Конечно, только причем тут утвержедния из вашего первого комментария?
> Возможно, предостерегать надо от вас, а не от меня. До свидания ещё раз, и всего хорошего вам.
Вам лень прочитать то что я написал и ответить, вместо этого вы пишите бессмысленный высокомерный комментарий, зачем? Не лучше ли было написать по существу, а не пытаться как то нелепо себя обелить?
Вообщем неконструктивный разговор, да всего хорошего :)
saggid
Я не люблю вести беседы с высокомерными людьми. Я с радостью поддержу беседу и разъясню всё более подробно, если человек внимательно читает мой текст и обращается с уважением к собеседнику. Не так уж часто в этом мире встречаешь умных людей) Но когда этот умный человек через каждое слово пишет тебе «ну и нафига?» — желание объяснять ему что-то после этого полностью пропадает)
Отвечу на ваши вопросы.
1. Шаблонизаторы не зло, в Riot.js используются те же самые шаблоны. Здесь также разделяется логика от отображения, но при этом они находятся недалеко друг от друга и по сути являются единым целым)
2. Вообще, можно и редактор разделить на два окна, да. Но более проблемно то, что обычно шаблон и его JS логика находятся в разных файлах (и даже папках) вашего приложения, что просто является менее удобным вариантом, чем когда всё это дело лежит в одном файле в целостном виде.
3. Я вообще не понял вас. Я же написал, что в Riot вместо списков event listener'ов используют атрибуты onclick, onmouseover, и так далее. Они, кстати, не добавленные авторами библиотеки же, как подумал один из комментаторов выше. Эти атрибуты полностью соответствуют спецификации HTML, и авторы Riot в этом плане ничего от себя не придумывали, они их лишь перехватывают и обрабатывают их своим кодом, так сказать.
4. Subview всё равно не избавит вас от необходимости изучения кода же) просто чуток облегчит проблему. В Riot тоже, кстати, компоненты прекрасно вкладываются друг в друга, чем я неоднократно уже пользовался. Те же самые subview'ы, в общем.
5. Классы из дивов иногда приходится удалять при изменении логики ранее написанных компонентов в соответствии с новым ТЗ) Я лично просто с этим несколько раз столкнулся, и пишу то, что мне было неприятно делать при переработке какого-то сложного бакбоновского компонента.
6. Благодаря серверному рендеру убиваются сразу два зайца: посетитель ваш мгновенно видит контент на открытой странице и не ждёт подгрузки JS логики и рендеринга вёрстки, а поисковые боты не испытывают проблем со сканированием страниц вашего сайта.
7. Думаю, это лишь ваши предположения о том, что это может быть неудобно) У меня абсолютно другое мнение по данному вопросу: написанный таким образом компонент намного удобнее изучать, чем Бакбоновские шаблоны с JS-логикой в отдельном файле (на котором я сам лично довольно много всего понаписал за время своей работы).
8. В реальности такая необходимость возникает только в особых ситуациях, в которых и на Бакбоне вам также придётся создать свои отдельные listener'ы в методе инициализации вашего View'а. Например, когда надо отслеживать события изменения размера окна браузера, скроллинг и клики мышью, и так далее. Я про такие ситуации говорил. Здесь конечно же не засунешь эти event listener'ы куда-то в тело вёрстки вашего компонента)
9. Насчёт серверного рендера я уже ответил, зачем оно нужно)
lega
slayerhabr
Я так понимаю Вы из Сколково?