Comments 45
Если честно не очень нравиться идея загаживания view подобными методами. Также MutationObserver — хорошо, но есть еще и стандартные метод remove к которому можно привязать удаление компонента.
А еще для подобного есть вариант использовать тот же View из бэкбона: создали view MyDate там теже методы по сути render, initialize, remove ничем не отличается и по использованию тоже, разве что нет MutationObserver, так необходимость в нем возникает крайне редко и в очень специфичных случаях. Вам и так сообщать об удалении вызвав ветод remove смысла слушать кучу сообщений от браузера без реальной нужды не вижу.

Имхо идея и реализация сырые, надо бы продумать.
Нет, всё это как раз обдумывалось.
1) Смысл «загаживать» view — удобство в использовании. Мне лично намного приятнее написать в шаблонах вот такой простой вызов без лишних инициализаций/ручных добавлений методов и т.д. Это сокращает объём кода. И потом, почему собственно не view — он разве не для этого предназначен?
2) По поводу использования отдельного view — недостаток всё тот же, ручное прописывание лишнего кода. Вам же надо сначала проинициализировать его (прописав это в render), потом деинициализировать, и так на каждый элемент. Самим отслеживать момент деинициализации, и не дай бог ошибётесь, будет мемори лик, который потом замучаетесь искать.
3) > Вам и так сообщать об удалении вызвав ветод remove
Это только один из подходов. Можно не вызывать remove, а сохранять view и всю его DOM-структуру в памяти, чтобы ускорить отрисовку при следующем вызове.
4) > слушать кучу сообщений от браузера без реальной нужды не вижу
Ну тут на вкус и цвет. Я стараюсь не писать код, который можно не писать — из этого всегда и исхожу. Этот плагин сокращает количество кода в приложении, вот и вся «реальная нужда». «Куча» сообщений не такая большая, посмотрите, как реализован MutationObserver. Если вы перерисовали view целиком, присвоив родительсокму элементу новый HTML, у вас вызовется одно сообщение в MutationObserver.
Вам же надо сначала проинициализировать его (прописав это в render), потом деинициализировать, и так на каждый элемент
А вы до сих пор вручную управляете вложенными вьюхами?
Я их вообще почти не использую, если вам это так интересно. Мне не нравится подход Marionette и подобных. Потом, это ведь всего лишь один частный подход, который никак не реализован на уровне самого Backbone.
Я к тому, что если реализован нормальный менеджмент вложенных вьюх, то ручного прописывания и лихорадочного поиска мемори ликов не требуется.
Но он должен быть реализован, так? То есть вместо Backbone.Component вам нужен какой-то другой инструмент, выполняющий эту функцию по-своему. А мне например в моём проекте этот инструмент не нужен, я не хочу его использовать.
Хорошо, когда есть альтернатива, правда?
Хорошо, когда есть разумная альтернатива. Когда она негодная, то лучше бы ее не было.
Ну так не используйте, разве кто-то заставляет? Тогда для вас её не будет.
Потом, поправьте, если я не прав. От мемори-ликов вас предположим ваша система менеджмента вложенных вьюх спасёт, но она не спасёт от необходимости где-то прописывать создание view на каждый ваш вложенный элемент. А это лишний код.
Поправлю: вложенные вьюхи прописываются декларативно. Вот как это сделано у меня:

var MyView = MyAbstractView.extend({
	__children__: {
    	'.js-player': ViewPlayer,
    	'.js-gameFeed': [ViewGameFeed, {
			param1: 'hello',
			param2: 'world'
		}]
	}
});;
Да, вполне пригодно. Но это же ваш собственный велосипед? Если собственный, тогда какой смысл сравнивать, в качестве готового решения другой человек его использовать не может.
То, что вы сейчас выложили — тоже ваш собственный велосипед. Вы написали статью на хабр, а я нет, вот и вся разница.
Управление джейкверийными плагинами умещается в один-единственный метод в моем велосипеде (и который я, к тому же, выкинул, так как не уверен, что это вообще нужно).
> То, что вы сейчас выложили — тоже ваш собственный велосипед.
Правильно. И я его делал потому что не нашёл готового решения. А не нашёл я его потому что его по сути нет (вот и вы ваш плагин забросили). О чём разговор-то тогда? Что мы сравниваем?
Это вы вообще-то завели разговор о том, чей велосипед менее велосипеден:) Я свой велосипед не забросил, если что, просто сейчас он мне по работе не нужен, поэтому активно не улучшается.
Нет, вы не поняли. Я не о велосипедности как таковой, в ней ничего плохого нет (любая разработка — чей-то велосипед так или иначе). Я не употреблял слово «велосипед» в негативном значении.
Я только о том, что я решал проблему, готового решения которой не нашёл, поэтому к чему эти вопросы «зачем»? Ну затем, что решения не было.
Ваш тезис был, что мою наработку другой человек не может использовать. Я его корректно опроверг?
Некорректно:
1) у вас нет документации
2) о вашей наработке кроме вас никто не знает (0 звёздочек на гитхабе)
То есть это решение не существует ни для кого кроме вас. Я бы его никогда не нашёл, если бы вы здесь мне его не привели.
Так что я до сих пор не понимаю, что мы сравниваем и о чём разговор.
У вас зато тестов нет:)

Нет, серьезно — это я не понимаю, о чем речь.
Ну если обе стороны не понимают, о чём спорят, значит пора закругляться :)
Если хотите, это как раз альтернатива бесконечным вложенным вьюхам. Я видел проекты, в которых степень вложенности могла достигать 5-8 уровней, это абсолютно нечитабельный код.
Обычно по-настоящему требуется всего три уровня вложенности:
1) общий лэйаут
2) основные области страницы (меню, контент и т.д.)
3) повторяющиеся элементы
Лэйаут не обязательно должен быть вьюхой, т.к. собственной отрисовки у него по сути нет. Для повторяющихся элементов я предлагаю использовать компоненты. А для view оставить только области страницы.
В такой архитектуре вьюхи отвечают за слишком большие области, что ведет к непомерному их разрастанию, и, как следствие, нарушению всех принципов SOLID и вообще хорошего кода. Видел я проекты с малой вложенностью, некоторые классы разрастались на 2+ экрана — это абсолютно нечитабельный код.
Если область меню — слишком большая для одного класса view, у вас в проекте что-то не так с меню.
При чём 2+ экрана к тому, что я сказал? Я вроде достаточно ясно выразился: 1 view — одна область одного экрана.
Меню бывает разное. Посмотрите в гмейле на список папок/меток справа, например.

> 1 view — одна область одного экрана.
У меня такое ощущение, что вы сложных вещей не писали, простите.
Если вы не используете вложенных вьюх и код у вас ни разу не разрастался на более чем один экран (имеется ввиду простыня в редакторе) — ничего сложного вы не делали.
А, вы про экраны в редакторе? Тогда да, 2+ страниц вполне встречается. Не вижу в этом проблемы, хотя тут тоже на вкус и цвет. Меня куда больше напрягает скакать из одного файла в другой, чем по одному файлу, который отвечает за одну область экрана.
Не люблю простыни по ряду причин.

Во-первых, нарушается принцип единой ответственности. Один экран интерфейса часто делится на несколько областей, связанных слабо или вообще не связанных. Даже если это большая форма, которая вся пишет данные в одну и ту же модель, ни визуально, ни по смыслу эти области могут быть не связаны.
Во-вторых, чем меньше кусок, тем проще его написать, оттестить, поддерживать и осознать.
В-третьих, упрощается командная работа, т.к. можно делегировать небольшие, четко выделенные куски работы. Да и средства контроля версий тоже больше «любят» маленькие файлы (меньше вероятность конфликта при мердже и т.п.)
Да, но тут есть оборотная сторона: читабельность.
Если я должен просмотреть 5 файлов (а перед этим ещё и найти, какие файлы просматривать), чтобы понять, как работает одна небольшая область экрана, это ну никак не способствует общей читабельности кода. Если область экрана управляется одним классом, вся логика её работы у вас сразу перед глазами.
На мой вкус это перевешивает всё остальное. Как известно, код больше времени читается, чем пишется.
А я пожалуй поддержку предыдущего оратора, хорошо когда код отвечает за одно логическую единицу. Если наш класс рулит мего моделью и отвечает за свистелку справа и перделку слева. то залезая поправить хреньку вверхку придется прочитать код всех этих передлок и свистелок дабы понять где нужные вам методы. А еще хуже это когда в таком классе появляются утилитные методы которые юзают сразу несколько логических единиц, в итоге слабая связанность пропадает, а вы поправив одно легко ломаете другое.
лучше открывать один небольшой файлик отдельной перделки, окинуть взглядом и потом внести изменения, но зато быть четко уверенным, что поправив что-то тут в другом месте не сломается.
Кстати именно поэтому на проектах я ввел БЭМ (немного не по теме, но!) простыня из 1 css файла неподдерживая фигня которая всегда ломается, и точно не применима когда вы работаете в команде более 2 человек. Также и с js.
Скажем так если у вас выпадающее\выезжающее\раскрывающееся меню, есть кейсы когда скажем набор выезжающих вкладок меняется при изменении состояния приложения, а скажем на вкалдке меню могут присутсвовать неоднородные элементы. и вполне логично что у вас будет 1 вью на карка меню, и по каждому вью на вкладку. а может и во вкладке будет своя вьюшка.

P.S.
хотел дописать бы в нижестоящему коментарию, что главным образом я не люблю решения которые явно выпадают из общей архитектуры приложения, это часто имеет последствия и как правило плохие.
Ну хорошо, я согласен, что в отдельных случаях та архитектура, которую я привёл, не подойдёт. Я и не утверждаю, что она универсальна. Я сказал, что обычно такие сложности не требуются, и трёх уровней вполне достаточно.
Если семантика приложения такова, что в нём объективно есть многоуровневые вложенные элементы (как в этом меню, о котором вы говорите), конечно, логично использовать для него вложенные вьюхи. Но это скорее исключение и с моей субъективной позиции говорит о плохом дизайне интерфейса.
Я вам говорю о том, что пока решение выглядит слишком костыльно. И как я говорил реализация Component достаточно убога. Не совсем понятно как 2 компонента могут взаимодействовать. Точнее пока они по сути не могут.
Также возможны баги при связке со всякими байндерами и тд.

Вот тот же Backbone.UI их подход мне куда больше нравиться.
> Не совсем понятно как 2 компонента могут взаимодействовать.
Никак, это идеология. Слабая связанность и всё такое. Посмотрите, как это реализовано в Ember: там то же самое, компонент изолирован от внешней среды.
> Также возможны баги при связке со всякими байндерами и тд.
В самом по себе плагине такая возможность не заложена, успешно использую его в паре с байндером. Если напишете кривой код в activate/deactivate, вполне возможно будут проблемы, но тогда компоненты тут ни при чём.
Base действительно интересный проект. Буду следить за его развитием. Благодарю за наводку.
Скажите, а в чем проблема была с тем, чтобы просто прикрутить React.js в качестве библиотеки для таких компонентов? Она то лучше ваших велосипедов, и десятка других, которые есть на рынке. Ну и кроме того, это только библиотека компонентов, и не заставляет отказываться от бекбона, или того, что вы используете.
React — самостоятельный фреймворк с собственной идеологией. Его иногда используют в связке с Backbone, но вообще-то это немного из другой оперы.
Что? А вы не путаете теплое с мягким?

React это:
— библиотека, а не фреймворк;
— это V в MVC, поэтому с Backbone и используют.

И главное, что собственная идеология React заключается в том, чтобы не мешаться внутри приложения, а помогать его строить. Именно поэтому, это библиотека с совершенно четкой и единственной целью. И используется она для создания как раз веб-компонентов, подобно Google Polymer. Ну и по сути это тоже самое, о чем написано в посте.
Бог с ней, с терминологией. Давайте так: React — это opinionated решение (извиняюсь, не представляю как это адекватно перевести на русский), которое например говорит вам, что шаблоны использовать не надо (ну или предлагает в качестве варианта JSX). С «голым» Backbone у вас таких ограничений нет, Backbone.Component тоже оставляет отрисовку полностью на усмотрение разработчика. Хотите шаблоны — используйте шаблоны, хотите манипуляцию DOM — используйте манипуляцию DOM. Можете с сервера подтягивать отрисованные куски HTML.
То есть я старался не выходить за идеологию Backbone, с React это никак не получится.
Я не могу понять, чем ваше решение + Mutation Observer кардинально отличается от React?

Какая разница, что вы вызовете в методе render вашей Backbone.View. Вызовете вы рендер своего Backbone.Component или вызовете renderComponent React'а — суть никак не поменяется. В обоих случаях получаются черные ящики, которые внутри себя несут логику + верстку, и могут генерировать какие-то события во вне, чтобы например Backbone View могла на них реагировать, не вникая во внутреннюю реализацию.

Если в какой-то вьюхе вам не нужен шаблон — не используйте ни шаблон, ни React компонент. Если вам не нужна манипуляция с DOM — не используйте ее. Ваша библиотека отличается от React только названием и тем, что практически ничего не умеет, ну и легче по весу за счет этого, ОК.
> В обоих случаях получаются черные ящики
Это неверно. В случае Backbone.Component разработчик сам решает, как ему генерировать текст. Он может использовать любой шаблонизатор или сгенерировать в jQuery набор DOM-элементов и потом вызывать html(). Или просто строку склеить. То есть
1) это не чёрный ящик
2) нет никаких ограничений на метод генерации HTML
В случае React вам придётся использовать манипуляцию DOM либо JSX. То есть React накладывает свои ограничения на инструментарий разработки, Bacbkone.Component — нет.
Не понравилось, что Вы используете свой интерфейс. В Backbone метод инициалиции називается «initialize» a метод удаления — «remove». Предерживайтесь единых стандартов, тогда Ваша библиотека будет более удобна, так как использует общепринятое соглашение.
По поводу совмещения activate и initialize можно подумать. Имя remove мне использовать не хотелось бы, т.к. в целом смысл тут несколько другой, чем у remove в Backbone.View: remove удаляет элемент из DOM, а deactivate вызывается, когда элемент удалён со страницы.
Читал комментарии с большим наслаждением чем статью. Статья мне понравилась, но комментарии без лишнего объяснили детали не описанных в статье. Практически идеальное дерево комментарий и без троллинга.
Only those users with full accounts are able to leave comments. Log in, please.