Мы хотим выполнить несколько вызовов $ http в блоке выполнения модуля, в идеале выполнение должно завершаться только после завершения $ http и обработки до того, как произойдет компиляция dom.
Это не так-то просто, но следует рассмотреть.
Жасмин делает это путем установки флага, который позволит функции запускаться и ждать обратного вызова, пока флаг не будет установлен в true
или пока не сработает тайм-аут.
В основном примерно так:
var flag = false;
$http(...).success(flag = true);
$timeout(function () {
flag = true;
// Or add some error handling stuff here
}, 5000);
while (!flag) {};
Это некрасиво, но должно работать. Приведенный выше код не тестировался, поэтому вам может потребоваться его немного изменить. Здесь уже поздно. Надеюсь, что-то поможет вам, пока не появится что-то более красивое.
+1
В какой-то момент это действительно приводит к невозможности нарисовать причудливый экран загрузки с помощью директив angular ...
+1
Разве $routeProvider
с resolve
решает эту проблему? Может я не понял в чем проблема ...
Это больше для поддержки инициализации асинхронного модуля. С учетом сказанного, мне это больше не нужно в моих текущих проектах.
@shahata $routeprovider
делает это, но не каждый вариант использования обещания run
s использует маршруты. В моем случае это для модуля, который является оболочкой для директивы и не имеет ничего общего с маршрутами.
+1
проверьте, возвращает ли функция запуска обещание, и выполняйте его только тогда, когда оно разрешено. поскольку runBlocks
- это массив функций, это совсем не должно быть сложно
+1
+1 досадно, что это проигнорировали
есть идеи, когда он приземлится? так неприятно перемещать элементы инициализации для разрешения в маршрутизаторе, в основном потому, что иногда код инициализации не зависит от URL-адреса (он же должен быть инициализирован для любого типа URL-адреса, который пользователь приходит в ваш SPA)
Я не думаю, что с этого момента angular получит какие-либо улучшения. все они добавляются в angular 2.0
как долго недоделанный метод run
будет оставаться синхронным? Хорошо и понятно, что config
не поддерживает асинхронные вызовы, поскольку у вас нет провайдеров, которые выполняют вызовы $http
, а run
поддерживает. посмотрите, какие взломы вызваны отсутствием этой функции (которая должна была присутствовать с самого начала)
https://github.com/philippd/angular-deferred-bootstrap/blob/master/src/deferred-bootstrap.js
это неловко
+1
@btford изучает, как варианты использования вокруг этого могут поддерживаться через новый маршрутизатор, а не внутри блоков выполнения.
+1
+1
+1
+1
Основная проблема заключается в том, что $q
создается внутри модуля, который загружается при запуске runBlocks. Это означает, что нам нужно будет каким-то образом извлечь «некоторые» службы (или, возможно, модули) и сначала создать их, а затем выполнить второй проход, который загружает остальные модули (и службы, блоки запуска и т. Д.) После того, как $ q был создан.
@lgalfaso - возможно, вы могли бы изучить это немного подробнее в рамках своей $injector
работы позже на этой неделе (или на следующей)?
Я знаю, что это всего лишь обходной путь, но обычно я решал проблему наличия некоторой логики асинхронной начальной загрузки с помощью маршрутизатора angular ui и наличия корневого абстрактного состояния в сочетании с разрешением. Первым всегда должно быть разрешено корневое абстрактное состояние, поэтому это хорошее место для загрузки настроек, отображения анимации загрузки и т. Д.
Это было бы действительно здорово.
: +1:
Жду этого исправления. Надеюсь, что он появится в 1.4
+1
У меня есть еще один вариант использования: мне нужно запустить мои смоделированные конечные точки с помощью вызова $ http при запуске (для кеширования некоторых данных) ...
+1
+1
просто наткнулся на это тоже ...
@petebacondarwin, думаю, можно продолжить загрузку всех остальных модулей, но отложить
в качестве альтернативы $ routeProvider может предложить настраиваемый параметр функции, который должен отложить рендеринг начального маршрута.
+1
+1
Вот возможный обходной путь: http://plnkr.co/edit/vi7mDjmD4NpZAoP7MVzr?p=preview
Идея состоит в том, что Angular фактически дает вам возможность создать собственный инжектор из набора модулей. В этом случае я отложил компиляцию $rootElement
до тех пор, пока не будут выполнены несколько обещаний ( resolves
). Это POC, и будет ряд других наворотов, которые понадобятся, чтобы подготовить эту постановку. Помимо всего прочего, вам нужно будет ловить ошибки в разрешении, а не просто проглатывать их.
+1
Это в основном руководство для тех, кто хочет попробовать; В настоящее время процесс начальной загрузки выполняет следующие действия:
$rootElement
$rootElement
Сверху, при создании инжектора шаги следующие:
run
функции на будущееrun
функцииВот несколько ключевых моментов:
run
выполняются до компиляции $rootElement
$rootElement
$q
разрешает обещания во время цикла дайджеста _only_Это:
run
которая возвращает обещание, и обещание должно быть разрешено до запуска приложения, то перед начальной компиляцией будут циклы дайджеста (это может нарушить существующие приложения)config
вводится поставщиками, а не экземплярамиКакое бы ни было решение, необходимо обрабатывать эти случаи
+1
любые новости?
Я просто хочу загрузить некоторые настройки конфигурации до того, как приложение действительно запустится.
+1
Я бы загрузил некоторые асинхронные данные после начальной загрузки, когда все мои фабрики работают, и до компиляции.
@dagingaa : Я бы выбрал ваше решение в качестве обходного пути! Благодарность
Обновление до @dagingaa : цикл for замораживает мои браузеры, не очень хорошо ...
https://jsfiddle.net/tuxmachine/t4d63vnw/
Вот как я решил это для реализации токена OAuth, которая требовала разрешения первоначального вызова ajax перед инициализацией остальной части приложения.
Не будет работать, если у вас есть несколько блоков асинхронного запуска.
+1
+1
+1
Прошло два года с момента открытия вопроса, но до сих пор нет хорошего решения
@vladmiller Есть решения, но, возможно, вы не чувствуете, что они хороши:
$onActivate
в компоненте верхнего уровняПомещение нетривиальной работы приложения в блоки .run
затрудняет модульное тестирование вашего кода. Так что мы не хотим поощрять это. Перенести это в Ice Box мы вряд ли сможем.
@petebacondarwin Я бы с вами не согласился; все ожидают, что angluar будет простым и интуитивно понятным, вместо этого вам нужно либо реализовать свой собственный модуль начальной загрузки async, либо модуль начальной загрузки в другом месте. На мой взгляд, это усложняет angular.
Можете ли вы также объяснить, что вы имеете в виду, когда говорите, что асинхронный код в .run
затруднит тестирование?
Извиняюсь за мой предыдущий грубый комментарий.
Спасибо
@petebacondarwin Я не понимаю, как это затрудняет тестирование. если вы поместите код инициализации в службу, вы можете просто посмотреть / имитировать / сравнить результаты, которые вы ожидаете от макета HTTP-бэкэнда, независимо от того, выполняется он внутри блока .run
или нет. наличие кода за пределами angular из-за обходных путей из-за отсутствия асинхронного запуска - вот что делает практически невозможным тестирование
Как дела?
Другой подход: http://plnkr.co/edit/8XGSNOzzRGvgNSSnXx3M?p=preview
Решение @petebacondarwin сработало для меня
Поскольку существуют обходные пути, а поддержка блоков асинхронного запуска может усложнить загрузку, я не думаю, что мы будем реализовывать эту функцию.
Простая функция, но ее сложно реализовать. 😕
+1 за эту функцию
+1
+1
Решение @petebacondarwin работает хорошо.
+1. :(
+1
+1
+1
+1
Мы не собираемся этого делать.
+100, все обходятся ужасно.
@ Eduardo-Julio - мы не собираемся реализовывать эту функцию, так как это значительно усложнит загрузку приложений AngularJS. Добавление дополнительных +
s не поможет.
Самый полезный комментарий
Простая функция, но ее сложно реализовать. 😕