Template + jQuery + MVC = jsMVC

    Разрабатывая сайты мне всегда хотелось облегчить себе жизнь, так я познакомился с jQuery. Все было бы хорошо если бы проекты не погружались в зыбучую смесь UI и js кода. Следующим этапом стало то что мы выделили UI Шаблоны в отдельные файлы, код стал более чистым, но, черт побери, все равно приходилось писать кучу UI кода, например вставка и настройка дополнительных компонентов в шаблон, event bind, надписи и т.д. И только после всего этого на выходе получался нужный нам компонент. Возникало, конечно, много проблем, особенно когда дизайнер менял шаблон, но все это решаемо.
    Мне всегда хотелось что бы дизайнеры рисовали мир, а програмисты оживляли его. И желательно что бы эти миры практически не пересекались и давали свободу и тем и другим. И так перейдем к сути.
    jsMVC состоит из трех вещей:
    • Компонент
    • Шаблон 2.0
    • Компиляция


    Компонент



    — слайд 3 —
    Компонент состоит из Шаблона+CSS, js«класса» + декларативное описание.
    js«class» определяется в пространстве имен jsMVC.Components. и имеет примерно такой вид:
    jsMVC.Components.Button = {
      Init: function(){// Вызывается после добавления объкта в дом
        jsMVC.Components.Component.Init.call(this);//Базовый метод...
        //<Действия>
      },
      SetEnable: function(flag){...}, // Определяем геттер и сеттер для свойства Enable
      GetEnable:function()  {...}
      //<Опеделедяем еще кучу методов...>
    }


    * This source code was highlighted with Source Code Highlighter.


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

    Далее декларируем свойства и события:

    — слайд 5 —
    jsMVC.CreateCompileInfoByObject(
    {
      Name: 'Button',
      Properties: {
        Enable: {
          Type: 'Boolean',
          Access: 'GETSET'
        },
        Text: {}
      },
      Events: {
        onClick: {}
      }
    });


    * This source code was highlighted with Source Code Highlighter.


    Указание типа и доступа свойств является не обязательным.
    Декларирование нужно для компиляции и редактора.

    Шаблон


    Шаблоны состоят из HTML тегов, других компонентов, казаний событий, установки свойств.
    Для примера Expander
    jsMVC.Templates.Expander =
    '<div>'+
      '<div name="content"/>'+
      '<div class="expander-control">'+
        '<component name="bToggle" type="Button" class="cExpander-cButton-bToggle">'+
          '<properties>'+
            '<key name="Text" value="*"></key>'+//Установка свойства Text
          '</properties>'+
          '<events>'+
            '<key name="onClick" value="Toggle"/>'+//Биндим событие
          '</events>'+
        '</component>'+
      '</div>'+
    '</div>';


    * This source code was highlighted with Source Code Highlighter.


    Можно сделать и такое
    jsMVC.Templates.TestComponent = '<div>'+
      '<component type="Expander">'+
        '<content>'+ //по умолчанию into="content", Вы помните что в Expander есть тег с именем "content"?
        '<div> Test TEXT </div>'+
        '<component type="Button">'+
          '<properties>'+
            '<key name="Text">Click Me</key>'+//Установка свойства Text
          '</properties>'+
          '<events>'+
            '<key name="onClick" value="Clear"/>'+//Биндим событие
          '</events>'+
        '</component>'+
        '</content>'+
        '<content into="bToggle">'+// Добавим чтонибудь в клавишу
          '<div> Test 2 </div>'+
        '</content>'+
      '</component>'+
    '</div>';


    * This source code was highlighted with Source Code Highlighter.


    Компиляция


    При первом создании объекта происходит компиляция Шаблона и Js«класса» в js функцию которая создает объект. При этом с помощью декларации компонента проверяются названия свойств, события и т.д.

    — слайд 7 —
    Вызвав эту функцию, на выходе мы получаем jQuery объект, который содержит:
    • все методы js«класса»
    • объект Components в который будут помещены jQuery обьекты (теги, компоненты) отмеченые атрибутом «name»
    • объект Events который будет содержать все забинденые события


    Далее поместив объект в DOM страницы необходимо вызвать метод Init(), по умолчанию этот метод вызовет метод Init() у всех вложеных компонентов.

    Производительность


    Так что насчет производительности? Для тестов был взят простой объект:
    <div class="menu>
      <div class="menu-background"/>
      <span name="text" class="menu-text"/>
    </div>


    * This source code was highlighted with Source Code Highlighter.


    Суть теста в том что бы создать 1000 — у объектов, установить в span.menu-text текст «ТЕСТ».
    Тест проводился на FF3.0.3, AMD 64x2 4800+, 2.51ГГц, 2Gb RAM, WinXP SP2


    — слайд 9 —
    jsMVC,SetText() — получил высокую производительность, так как метод SetText устанавливает текст через innerHTML.
    DOM,innerHTML — создание всех элементов через createElement и т.д.,
    jQuery + innerHtml — создание основного элемента и заполнение его через innerHTML, результат практически совпадает с полным созданием шаблона через jQuery
    Полная статистика:
    Time:700 ms Name: "jQuery", $(Template), $(TAG.class[@atr="..."]), $().text()
    Time:591 ms Name: "jQuery", $(Template), $(.class), $().text()
    Time:441 ms Name: "jQuery", $(Template), $(obj[0].childNodes[]), $().text()
    Time:463 ms Name: "jQuery", $()[0].innerHtml, $(obj[0].childNodes[]), $().text()
    Time:680 ms Name: "jQuery", $()[0].innerHtml, $(TAG.class[@atr="..."]), $().text()
    Time:565 ms Name: "jQuery", $()[0].innerHtml, $(.class), $().text()
    Time:383 ms Name: "jQuery", $()[0].innerHtml, $(.class), obj[0].innerHTML
    Time:471 ms Name: "jQuery", $()[0].innerHtml, $(#id), obj[0].innerHTML
    Time:484 ms Name: "DOM", createElement(), $(TAG.class[@atr="..."]), $().text()
    Time:391 ms Name: "DOM", createElement(), $(.class), $().text()
    Time:297 ms Name: "DOM", createElement()+innerHtml, $(obj.childNodes[]), $().text()
    Time:261 ms Name: "DOM", createElement(), $(DOMElement), $().text()
    Time:357 ms Name: "DOM", createElement(), $(DOMElement), $().html()
    Time:101 ms Name: "DOM", createElement(), $(DOMElement), innerHTML
    Time:113 ms Name: "DOM", createElement(), $(DOMElement), innerHTML, cache element
    Time:303 ms Name: "jsMVC", $().text()
    Time:129 ms Name: "jsMVC", SetText() — spec object method

    Итог


    • Каждый компонент может содержать множество дочерних компонентов.
    • Сокращение времени разработки
    • Производительность близка к ручному созданию дом (с оговорками)
    • Дизайнеры создают мир, программисты оживляют его.


    Проект распространяется под GPLv3
    Буду рад критике, багам, идеям и предложениям.
    Текущая версия 1.0alpha, есть еще недоделки и баги.

    В конце недели будет выпущен конструктор компонентов WYSIWYG (готов на 80%), полностью написаный на jsMVC.

    Исходники.

    П.С.: я думаю есть куча похожих идей, хочу лишь предложить одну из реализаций.
    П.С.2: С анг. языком у меня проблемы, был бы очень рад если бы кто нибудь помог мне перевести эту заметку, если она заинтересует людей.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 25

      +3
      А в открытом доступе есть какие-то живые сайты, разработанные с помощью jsMVC?
        0
        Разработка началась 2 недели назад, пока на ней существует только один сайт, конструктора компонентов.
        +1
        Слишком мощная тачка для таких тестов =(

        p.s имел ввиду что далеко от реальности…
          +1
          тут можно провести тесты на других машинах
          0
          Я так понял что я еще далек от понимания этого.
          Пример вроде ничего особого не делает, а кода запудрен %(

          Было бы хорошо более расписать, для менее доходящих…
            0
            вам возможно на данном этапе такое не нужно, не всегда ведь нужен белаз для вывоза строительного мусора с квартиры.
            0
            хм, а что скачать и попробовать можно только став project member?
              +1
              помоему из svn сливать(read-only) без ограничений можно.
              0
              могу помочь с английским, приват
                +3
                для доработки jsMVC.Templates.TestComponent советую обратить внимание на ejohn.org/blog/javascript-micro-templating/
                таким образом гораздо удобнее шаблоны редактировать
                • UFO just landed and posted this here
                  0
                  Ой, только не надо складывать несколько строк, это очень медленно работает в IE:
                  '<div>'+
                    '<div name="content"/>'+
                    '<div class="expander-control">'+
                  ...
                  


                  Лучше добавлять все элементы в массив, а потом объединять: [...].join(''). На Quirksmode можно посмотреть тесты производительности (там два теста с innerHTML: один с простым объединением с строк, а другой с добавлением их в массив).
                    +1
                    Да, но мы делаем это один раз, при старте приложения, во вторых это для удобства разработки, а в третьих по тестам падение производительности наблюдается только если более 100 слов(10символов) соединяешь, так что это не значительно, а на реальном сайте можно и одной строчкой сделать.
                      0
                      в некоторых случаях через join еще и дольше получается…
                        0
                        За ссылку на Quirksmode, спасибо
                        0
                        простите за тупой вопрос, а где тут у вас модель?
                          –2
                          Вопрос очень хороший, видимо погрузивший в создание конструктора и самой jsMVC, я утерял нить.
                          Нарисовав сейчас на бумаге пример с комопнентом Button, получилось что Вид -это шаблон и цсс, вид так же отвечает и за рендеринг, но например на клавише есть текст, а его устанавливает js«class»-SetText, а значит Вид больше чем просто шаблон:(,
                          Контроллер — это события, а значит однозначно js«class», Модель — оперирует данными, SetEnable и SetText изменяют внутренние переменные в this.Properties и одновремменно вызывают методы(например text() или innerHTML для объекта) изменения Вида.
                          Получается как то все размазано, да вроде как отделили вид, так как мы его можем менять налюбой другой, при условии что назначим все аттрибуты «name», с другой нет четкой границы между моделью и контролером, видом и моделью. Так что ваш вопрос привел меня к тому что я задумался а настолько ли это MVC, хотя JS с его связыванием далек от ООП и воозможно применение чистого MVC вылилось бы в большие грабли и усложнило разработку продуктов, незнаю…
                            +1
                            бардак в голове — бардак в коде.
                              0
                              взгляни на objective-j — cappuccino.org/
                            +1
                            Только за одни диаграммы можно уже ставить плюс :) (подачу материала)
                              0
                              Я правильно понимаю, что Вы всю верстку хотите засунуть в js файл?
                                0
                                Как я понял — да (
                                0
                                не очень удобно и красиво шаблоны запихивать как строку в переменную.
                                  0
                                  да, без генератора компонентов похоже с таким подходом не обойтись
                                  • UFO just landed and posted this here

                                    Only users with full accounts can post comments. Log in, please.