Организация кода в JavaScript: MVC?Компоненты самопереноса? - PullRequest
2 голосов
/ 18 марта 2011

Я создаю чрезвычайно JS-тяжелое веб-приложение.Я говорю, что это JS-тяжёлый, потому что большая часть выполняемой работы выполняется на клиенте (хотя есть некоторая синхронизация назад и вперед на сервер с использованием AJAX и XMPP).

Это мой первый разпостроение чего-то такого масштаба в чистом JS (с использованием jQuery), поэтому я начал с того, что организовал свой код с использованием MVC способом, смоделированным после Rails.Например, если пользователь нажимает кнопку, в объекте Controller вызывается метод, который извлекает некоторые данные из моделей и затем передает данные в функцию представления.Я делаю это практически для всего, даже для простых действий, таких как показ небольшого всплывающего окна.

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

Кажется, что было бы более разумно разбить представления на компоненты, которые будут экземплярами объектов / функций Javascript.Например, вместо ...

var itemListHTML = '<ul id="item-list"><li>item1</li><li>item2</li></ul>';
jQuery('#container').html(itemListHTML);

... я мог бы вместо этого иметь ...

components.itemList.render();

Итак, здесь есть только компонент с именем itemList.Поскольку все данные хранятся на клиенте, эти компоненты могут мгновенно получить доступ ко всем данным, необходимым для их создания и управления.Я полагаю, что я все еще использовал бы MVC, но не было бы необходимости в действиях контроллера, которые отвечают за весь вид.Если я хочу обновить одну часть пользовательского интерфейса, я просто вызываю whateverComponentControlsThatArea.redraw(), и он перерисовывается.

Я уверен, что кто-то делал это раньше.Есть ли название для этого стиля организации кода?Какие-либо руководства или рекомендации по его внедрению?

Ответы [ 3 ]

2 голосов
/ 18 марта 2011

Вы действительно должны заглянуть в jquery.tmpl (http://api.jquery.com/jquery.tmpl/), чтобы создать быстрый шаблонизатор javascript, идеальный для построения вашего рендеринга вида.

2 голосов
/ 18 марта 2011

В настоящее время доступно несколько Javascript MVC-фреймворков
JavaScriptMVC , PureMVC , Sammy.js , например.
Рендеринг представлений или вложенных представлений обычно обрабатывается с помощью какого-либо механизма шаблонов.
JavaScriptMVC имеет модуль EJS , который смоделирован на ERB, что я нашел довольно полезным. Шаблоны могут быть скомпилированы в функции для ускорения процесса производства.
Существуют и другие шаблонные решения, например, Джон Микротемплатинг Ресига и и многие другие

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

1 голос
/ 12 октября 2011

Немного опоздал на вечеринку, но у меня тут 0,02 доллара, что я не уверен, что делать с ...

Забыть о (типичном) Web-MVC (то есть: RailsMVC, etи т.д.) на секунду:

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

В идеале, с точки зрения программного обеспечения, MVC должен отделить то, что делает пользователь, от того, что составляет контент (на основе действия), от того, что составляет представление (на основедействие).

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

В простом псевдо-примере вместо потока, который выглядит следующим образом:

Action Loads Controller -> Модель нагрузок контроллера -> Запросы контроллерамодель-> Модель отвечает на контроллер -> Просмотр загрузок контроллера -> Контроллер подает данные для просмотра -> Просмотр страницы отправки на контроллер -> Страница выходов контроллера

Почему бы не что-то вроде:

Контроллер прослушивает действие(addEventListener) -> Контроллер превращает действие в логику состояния -> Контроллер уведомляет модель (наблюдатель) ИЛИ Опросы модели Контроллер -> Изменяет состояние модели на основе логики и собирает / сортирует все данные -> Просмотр уведомлений модели (наблюдатель) ИЛИ Просмотр опросовМодель -> Просмотр изменений состояния на основе логики -> Просмотр отрисовывает все компоненты на основе Data + ViewState (innerHTML ИЛИ documentFragment).

Это выглядит немного дольше, но на самом деле все красиво и по-отдельности.С помощью View (или View Manager, или как вы хотите об этом думать), который определяет, какие окна находятся на странице, и как составляется каждое окно и куда направляются данные внутри каждой статьи в каждом окне ...

... теперь у вас есть шаблон MVC, но у вас также есть возможность сказать:

View["mainpage"] = {

    data : { tweets : [{id:...}...]/* et cetera - pushed by Model, not Controller */ },
    layout : [ "Header", "Carousel", "Articles", "TwitterFeed", "RSSFeed", "Footer" ],

    // if your system is this clean, you could even prototype the content-builders
    // rather than defining them in each ViewState - you'd just need layout, then
    buildPage : function () {
        var page = document.createDocumentFragment();
        for (/* everything in this.layout */) {
            View.build[this.layout[i]](this.data, page);
        }
        document.body.appendChild(page);
    },

    cleanUp : function () { /* fancy or simple DOM cleaning for state-change */ },

    // grabs SubView by expected handle (id="tweetfeed" or whatever) and replaces it
    // observer functionality, for views to automatically update as data changes
    updateView : function (view, newData) { ... },

    addData : function (data) { this.data = data; }, // for Observer

    /* Observer - if you want to run the WHOLE site with AJAX from index.html
     * clean up old (ex:"main") page and build and/or transition new (ex:"media") page
     * could be unique for each page, for custom transitions, or just prototype it */
    changeState : function (newState, newData) {
        View["mainpage"].cleanUp();
        View[newState].addData( newData );
        View[newState].buildPage();
    }
}

И теперь вы определили всю свою главную страницу.Конечно, это будет дополнительная работа, поддерживая не только определения для вашей главной страницы, но и для каждой страницы / раздела.... а затем вам нужно создать функции, которые будут создавать каждое вложенное представление - но компонентный дизайн - это именно то, о чем вы спрашивали.По сути, для каждого виджета у него будет своя логика построения.Это то, что делают представления - у них либо есть отдельный шаблон, который используется повторно, либо у них есть функция, которая каждый раз работает одинаково.

А атомарное представление - это то, где вы имеете дело с функцией, которая создает1 элемент (1 твит, 1 публикация, 1 элемент магазина) и создает представление для этого.Наличие представления Single_Tweet, отправляющего один твит на страницу, 20 раз подряд было бы плохой идеей для производительности JS.

Но наличие push-твитов представления Single_Tweet по порядку,в массив твитов, который ваше представление Twitter_Feed помещает на сайт, называется A-OK.

Еще лучше, когда ваши страницы представляют собой представления, состоящие из виджетов представлений и состоящие из атомарных единиц представлений.И когда все это происходит вне DOM (например, innerHTML или documentFragment).

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

И в этом прелесть AJAX - старомодный MVC может произойти без контроллера, который знает все.

Контроллер просто содержит списокнажатые клавиши, координаты мыши, намерение нажатой кнопки ... И он сообщает модели, что что-то произошло.Модель делает все, что связано с состоянием / данными / манипуляциями с данными (сортировкой), и передает новое состояние или данные в представление, которое берет все это и помещает в HTML в указанном вами порядке.

Этооб этом.

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