Coffeescript, Backbone и порядок загрузки - PullRequest
3 голосов
/ 07 сентября 2011

Рассмотрим этот класс Coffeescript в приложении, где каждый класс живет в своем собственном файле.

class Manager extends Person
  title: titles["manager"]

Если этот файл загружается до объекта «титры», генерируется ошибка.Я предполагаю, что это из-за оболочки безопасности Coffeescripts, которая выполняет ".call (this)" при первой загрузке этого файла?

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

Разве это не вызывает раздражающих проблем порядка загрузки, или янеправильно что-то делаешь?

Ответы [ 3 ]

2 голосов
/ 07 сентября 2011

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

И если titles определено в другом файле, тогда область действия class Manager не имеет значения. Итак, это вопрос заказа. Как определяется titles?

Если бы мне пришлось отложить запуск какого-либо кода до полной загрузки всей страницы ($ (document.ready ()), я мог бы быть уверен, что все файлы javascript были полностью загружены до того, как какой-либо код фактически запустился.

Не совсем. $(document).ready() (обратите внимание на круглые скобки - функции document.ready нет ...) задерживает выполнение функции до тех пор, пока не будет загружен весь HTML-код страницы, что не означает, что загружен весь JavaScript. Вот хорошие новости: с точки зрения кода JavaScript, не имеет значения, были ли загружены другие файлы JavaScript, потому что все они работают по порядку. ( Примечание: Здесь я предполагаю, что вы не делаете ничего сложного, например, добавление дополнительных тегов <script> из своего кода JavaScript.) Так что, пока у вас есть

<script src="titles.js"></script>
<script src="Manager.js"></script>

Вы можете быть уверены, что Manager.js будет запущен только после titles.js.

Внимание! Использование $(document).ready() для заказа кода JS является распространенной ошибкой, которая может привести к путанице! Если ваш HTML выглядел следующим образом

<script src="Manager.js"></script>
<script src="titles.js"></script>

, где titles.js создает глобальный объект с именем titles, а Manager.js выглядит следующим образом

$(document).ready ->
  console.log titles

тогда вывод будет иногда будет titles, а иногда будет undefined. Зачем? Потому что, как документы говорят,

Если .ready() вызывается после инициализации DOM, новый переданный обработчик будет выполнен немедленно.

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

Итак, будь проще. Просто загрузите ваши скрипты в правильном порядке. Помните, что для практических целей ваши сценарии объединяются браузером по порядку в один файл JS.

2 голосов
/ 19 апреля 2012

Попробуйте CoffeeToaster:
http://github.com/serpentem/coffee-toaster

Он будет делать именно то, что вы ищете, предоставив директиву import, то есть #<<, т.е. :

#<< foldera/folderb/folderc/myfile

Вам не нужно сообщать расширение .coffee, плюс вы можете включить опцию packaging, чтобы иметь возможности для пространств имен, если вы привыкли к чему-то вроде:

#<< another/package/myclass
class SomeClass extends another.package.MyClass

Он имеет систему сборки, которая будет выводить один файл javascript для вас или несколько (в режиме отладки) для облегчения процесса отладки.

Посмотрите на README и пример использования по адресу:
https://github.com/serpentem/coffee-toaster/tree/master/usage

0 голосов
/ 07 сентября 2011

Это действительно проблема порядка загрузки, и titles в Manager относится к глобальному в этом случае, который не объявлен в данный момент.Если вы знаете, что titles объявлено глобально где-то еще, вы должны вручную убедиться, что скрипт был загружен первым.И да, проблема вполне может быть с защитной оболочкой.Но только в качестве рекомендации: это есть по уважительной причине.Вместо этого создайте себе пространство имен, которое вы экспортируете в глобальный объект.Глобальный объект живет в this (во время определения) или exports в узле.Я обычно помещаю эту однострочную строку поверх сценариев, которые должны иметь легкий доступ к глобальному объекту:

root = exports ? window

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

root.app =
  a: 1,
  a_fun: -> 1

class root.app.Cls
   method: => 1 + 1

root.app.obj = new root.app.Cls

Теперь в вашем глобальном объекте будет объект 'app' с 'классом' (так сказать) и объектом.

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