Как обрабатывать js-функции, когда мы используем DOM-готовое выполнение на основе разметки

Извините за долгое чтение, но было бы неплохо, если бы вы все равно могли поделиться своими мыслями.:)

Итак, методика описана в посте блога Пола Айриша здесь - http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution а затем расширена Джейсоном Гарбером здесь - http://viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution.

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

Объект будет выглядеть примерно так:

APP = {
  controller1 : {
    view10: function(){ ... },
    view11: function(){ ... }
  },
  controller2: {
    view20: function() {...},
    view21: function() {...}
  }
}

Тогда вы меняете свой <body> в

<body data-controller="controller_name" data-action="view_name">

а затем с некоторыми вкусностями JS, когда DOM готов, происходит автоматический вызов APP.controller_name.view_name(),

Это супер, потому что вы можете поместить все свои сценарии, готовые к выполнению в DOM, в одном месте, и эти сценарии выполняются без дополнительного кода.

А теперь актуальный вопрос: что делать с другими функциями JS для конкретного контроллера или представления / страницы, которые не должны выполняться, когда DOM готов, но когда происходит событие (например, onclick="someFunction()"?

Было бы очень хорошо, если бы эти функции были в пределах APP.controller_name пространство имен, потому что это поможет сохранить код. И с этим сказал, что в настоящее время я изменяю свой объект APP во что-то вроде:

APP = {
  controller1 : {
    view10: function(){ ... },
    view11: function(){ ... },
    extraStuff10: function: () {...},
    extraStuff11: function: () {...}
  },
  controller2: {
    view20: function() {...},
    view21: function() {...},
    extraStuff20: function: () {...}
  }
}

И это все хорошо - APP.controller1.view10() выполняется автоматически, и вы можете позвонить APP.controller1.extraStuff10() когда вам это нужно потом. Но есть один серьезный недостаток для этой структуры - view10() и extraStuff10() имеют абсолютно одинаковую структуру, поэтому вы не можете сказать, является ли extraStuff10() функцией, ожидающей выполнения при возникновении события ИЛИ, если есть фактическое представление /page, которая называется extraStuff, и содержимое этой функции будет выполняться при загрузке страницы.

Я подумываю об изменении функции view10 () на объект, который содержит функцию init() (и мы разместим скрипт для DOM-ready внутри) следующим образом:

APP = {
  controller1 : {
    view10: {
      init(): function(){ ... }
    },
    extraFunction10: function: () {...}
  }
}

Это даст четкое разделение функций, готовых к DOM, и других функций, но мне интересно, является ли это лучшим способом для достижения этой цели... Есть идеи?

1 ответ

Это хороший шаблон, но я бы порекомендовал немного разбить его на части, так как подход "один файл-все-их-все" скоро станет громоздким. Что происходит, когда ваше приложение увеличивается до 50 страниц? В итоге вы получите файл монстра для редактирования, который должен быть загружен целиком для самой страницы, что увеличивает время загрузки и анализа.

Меньшие файлы библиотеки JS, загружаемые динамически в зависимости от того, к какой странице обращаются, будут работать хорошо. Затем вы можете прикрепить функции к глобальному пространству имен APP, чтобы их можно было повторно использовать между страницами. Код вашего контроллера остается легким, как если бы он просто прикреплял простой клик или что-то еще, чтобы запуск уже загруженной библиотеки.

В этом может помочь переход к использованию менеджера требований для загрузки библиотек в правильном порядке, например, http://requirejs.org/docs/jquery.html

Другие вопросы по тегам