JavaScript

индекс
246,38

Шаблонизатор на основе объектной модели html

Прочитав предыдущий топик (http://habrahabr.ru/blogs/javascript/96588/) в сознании всплыла старая идеи. Подход известный, но то ли у него есть минусы которые я не вижу, то ли мы с гуглом друг друга не поняли. В общем, готового решения я найти не смог, поэтому за пару часов набросал свое. Но так как наши пути с джава скриптом на данный момент разошлись, опробовать его в реальном проекте не получилось.
Интересны два вопроса, какие вам видятся минусы и встречали ли вы похожие решения для javascript?


Каждый тег (например div) предстает в виде функции Htmls.div которая
на выходе отдает HTMLElement, а на вход принимает любое количество аргументов типа:
1) Object — используется для определения атрибутов.
2) String — текст
3) HTMLElement — вложенный тег
4) Array — список из текстов и тегов.

Два примера


Пример 1

Имеем
var items = ["x", "y"];


Хотим получить
<div>
  <div id="some" class="some-class">
    some div
  </div>
  some text
  <div>x</div>
  <div>y</div>
</div>




result содержит то что мы хотим.

var result;
with (Htmls) {
  result = div(
    div({ id: "some", class: "some-class" },
      "some div"),
    "some text",
    items.map(function (i) {
      return div(i);
    }))
  .outerHTML;
}


* This source code was highlighted with Source Code Highlighter.


Пример 2 из вышеупомянутого топика

data = {
  title: 'C pocket reference',
  type: 'PDF Document',
  tag: 'programming',
  created_at: '5.31.2010'
}
with (Htmls) {
  var tagUrl =   "tags/" + data.tag;
  var result = tr(
    td(data.title),
    td(data.type),
    td(a({href: tagUrl}, data.tag)),
    td(data.created_at))
    .outerHTML;
}


* This source code was highlighted with Source Code Highlighter.


Незамысловатый код
Htmls = (function () {
  function initTag(tag, args) {
    for (var i = 0; i < args.length; i++) {
      var arg = args[i];
      if (arg.constructor == String) {
        tag.innerHTML += arg;
      }
      else if (arg instanceof HTMLElement) {
        tag.appendChild(arg);
      }
      else if (arg.constructor == Array) {
        initTag(tag, arg);
      }
      else if (arg.constructor == Object) {
        for (var j in arg) {
          tag.setAttribute(j, arg[j]);
        }
      }
    }
    return tag;
  }

  function createTag(name, args) {
    return initTag(document.createElement(name), args);
  }

  return {
    div: function () {
      return createTag("div", arguments);
    }
  //можно добавлять другие теги
  }
})();


* This source code was highlighted with Source Code Highlighter.
–1
17 июня 2010, 10:48
9

комментарии (14)

0
l2k #
Прошлый топик решает совершенно другую задачу.

Лично для гибкости разработки, я абсолютно против слияния PHP с SQL/HTML, а JS с HTML. Это во много раз упрощает разработку.

Приведу простой пример:
Что вам нужно сделать, чтобы каждый тег ещё был с классом? А с дополнительным аттрибутом (например, я иногда использую sid)?

В примере habrahabr.ru/blogs/javascript/96588/ — не нужно ничего изменять в коде. Код остается ясным. И шаблон остается ясным.
0
dotneter #
>Что вам нужно сделать, чтобы каждый тег ещё был с классом? А с дополнительным аттрибутом (например, я иногда использую sid)?

Можете привести пример html?
0
l2k #
Html не имеет значения.
Я говорю про изменения.
При изменениях (например, верстка поменялась) вам нужно будет её переписывать на JS. И стараться ничего не потерять.

В template случае — вам нужно будет только не потерять переменные в шаблоне :)
0
dotneter #
<div>programming</div> => <span>programming</span>
"<div>{tag}</div>" => "<span>{tag}</span>"
div(data.tag) => span(data.tag)



Я не совсем улавливаю разницу.
0
l2k #
Проблема не в том, что нельзя этого сделать. Дело в том, что на это уйдет время:
1) Нужно понять где произошли изменения в html
2) Найти эти части в JS
3) Внести изменения ничего не потеряв.

Когда HTML состоит из нескольких кб — это сделать довольно проблематично и возникает много ошибок => больше тратится времени на исправления.
+3
slesar #
В таком стиле написан SquirrelMail. Вы знаете, это просто ад.
+1
vflash #
«arg.constructor == String» используйте typeof
из за with все работать будет значительно медленнее.
–2
tenshi #
typeof new String =?
+1
vflash #
и? вы что специально все строки создаете через конструктор String чтоб потом еб*** с определением типа?
–3
tenshi #
представь себе, специально.
я не ебусь, у меня есть замечательная функция $.is.string
0
GetWindowsDirectory #
Глупо. Почему вы выбираете именно такой путь?
0
tenshi #
когда часто вызываются методы строки, чтобы не происходило каждый раз создания нового объекта
0
ed_tsech #
Я уверен, что подобные решения уже есть, уже где-то видел такое и на JS, и на Ruby. Но это полное извращение. Писать разметку на языке программирование? Это не шаблонизирование. Это безумство.

К автору претензий никаких, ни у него одного возникают такие идеи.
0
dotneter #
JavaFX видели?

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