Как обрабатывать 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