Свойство разрешения $ routeProvider позволяет отложить изменение маршрута до загрузки данных.
Сначала определите маршрут с таким resolve
атрибутом, как этот.
angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: PhoneListCtrl,
resolve: PhoneListCtrl.resolve}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: PhoneDetailCtrl,
resolve: PhoneDetailCtrl.resolve}).
otherwise({redirectTo: '/phones'});
}]);
обратите внимание, что resolve
свойство определено на маршруте.
function PhoneListCtrl($scope, phones) {
$scope.phones = phones;
$scope.orderProp = 'age';
}
PhoneListCtrl.resolve = {
phones: function(Phone, $q) {
// see: https://groups.google.com/forum/?fromgroups=#!topic/angular/DGf7yyD4Oc4
var deferred = $q.defer();
Phone.query(function(successData) {
deferred.resolve(successData);
}, function(errorData) {
deferred.reject(); // you could optionally pass error data here
});
return deferred.promise;
},
delay: function($q, $defer) {
var delay = $q.defer();
$defer(delay.resolve, 1000);
return delay.promise;
}
}
Обратите внимание, что определение контроллера содержит объект разрешения, который объявляет вещи, которые должны быть доступны для конструктора контроллера. Здесь phones
он вводится в контроллер и определяется в resolve
свойстве.
resolve.phones
Функция отвечает за возврат обещания. Все обещания собраны, и изменение маршрута откладывается до тех пор, пока все обещания не будут решены.
Рабочая демонстрация: http://mhevery.github.com/angular-phonecat/app/#/phones
Источник: https://github.com/mhevery/angular-phonecat/commit/ba33d3ec2d01b70eb5d3d531619bf90153496831
angular.controller()
определениях контроллеров типов? В$routeProvider
вещах я думал, что вы должны использовать строковые имена контроллеров.angular.controller()
, вы можете присвоить результат этой функции переменной (var MyCtrl = angular.controller(...)
), а затем работать с этим далее (MyCtrl.loadData = function(){..}
). Посмотрите видео на eggheadВот минимальный рабочий пример, который работает для Angular 1.0.2
Шаблон:
JavaScript:
http://jsfiddle.net/dTJ9N/3/
Модернизированная версия:
Так как $ http () уже возвращает обещание (иначе отложенное), нам на самом деле не нужно создавать свое собственное. Таким образом, мы можем упростить MyCtrl. решить:
Результат $ http () содержит данные , статус , заголовки и объекты конфигурации , поэтому нам нужно изменить тело MyCtrl на:
http://jsfiddle.net/dTJ9N/5/
источник
Unknown provider: datasetsProvider <- datasets
function($http) { return $http({method: 'GET', url: '/someUrl'}) .then( function(data){ return data;}, function(reason){return 'error value';} ); }
Я вижу, как некоторые люди спрашивают, как это сделать, используя метод angular.controller с минимизацией дружественных инъекций зависимостей. Так как я только получил эту работу, я чувствовал себя обязанным вернуться и помочь. Вот мое решение (взято из исходного вопроса и ответа Миско):
Поскольку этот код получен из вопроса / самого популярного ответа, он не проверен, но он должен направить вас в правильном направлении, если вы уже понимаете, как сделать дружественный угловой код минификацией. Единственная часть, которая не требовала моего собственного кода, - это вставка «Phone» в функцию разрешения для «телефонов», при этом я вообще не использовал объект «задержки».
Я также рекомендую это видео на YouTube http://www.youtube.com/watch?v=P6KITGRQujQ&list=UUKW92i7iQFuNILqQOUOCrFw&index=4&feature=plcp , которое мне немного помогло
Если вас это заинтересует, я решил также вставить свой собственный код (написанный на coffeescript), чтобы вы могли увидеть, как я его заработал.
К вашему сведению, заранее я использую универсальный контроллер, который помогает мне делать CRUD на нескольких моделях:
источник
resolve
функцию в контроллере в последних версиях Angular? Так что должно быть объявлено прямо в конфиге, как здесь?$defer
сервисе, обратите внимание, что в версии 1.5.7 AngularJS вы хотите использовать$timeout
вместо этого.Этот коммит , который является частью версии 1.1.5 и выше, предоставляет
$promise
объект$resource
. Версии ngResource, включая этот коммит, позволяют разрешать ресурсы следующим образом:$ routeProvider
контроллер
источник
GET '/api/1/apps/:appId'
->App.get({id: $routeParams.appId}).$promise();
я не могу использовать, как это$route
для своей решимости и использования$route.current.params
. Будьте осторожны,$routeParams
все еще указывает на старый маршрут.Этот фрагмент кода удобен для внедрения зависимостей (я даже использую его в сочетании с ngmin и uglify ), и это более элегантное решение на основе домена .
В приведенном ниже примере регистрируется ресурс Phone и константа phoneRoutes , которая содержит всю информацию о маршрутизации для этого (телефонного) домена. Что-то, что мне не понравилось в предоставленном ответе, было расположение логики разрешения - главный модуль не должен ничего знать или беспокоиться о том, как аргументы ресурса передаются контроллеру. Таким образом, логика остается в той же области.
Примечание: если вы используете ngmin (а если нет: вам следует), вам нужно только написать функции разрешения с соглашением о массиве DI.
Следующим этапом является внедрение данных маршрутизации, когда модуль находится в состоянии конфигурации, и его применение к $ routeProvider .
Тестирование конфигурации маршрута с этой настройкой также довольно просто:
Вы можете увидеть это в полной славе в моем последнем (предстоящем) эксперименте . Хотя этот метод отлично работает для меня, мне действительно интересно, почему $ инжектор не задерживает создание чего-либо, когда он обнаруживает внедрение чего-либо, что является объектом обещания ; это сделало бы вещи оооооооооооооо намного проще.
Редактировать: используется Angular v1.2 (RC2)
источник
I really wonder why the $injector isn't delaying construction of anything when it detects injection of anything that is a promise object
Я предполагаю, что они пропустили эту функцию, потому что она может поощрять шаблоны проектирования, которые негативно влияют на отзывчивость приложений. По их мнению, идеальное приложение - это действительно асинхронное приложение, поэтому его решение должно быть на грани.Задержка показа маршрута обязательно приведет к асинхронному путанице ... почему бы просто не отследить состояние загрузки вашего основного объекта и использовать его в представлении. Например, в вашем контроллере вы можете использовать как коллбэки успеха, так и ошибки в ngResource:
Тогда в представлении вы можете сделать все что угодно:
источник
Я работал с кодом Миско выше, и это то, что я сделал с ним. Это более актуальное решение, поскольку
$defer
оно было изменено на$timeout
. Подстановка,$timeout
однако, будет ожидать период ожидания (в коде Миско, 1 секунда), а затем вернет данные, надеясь, что они разрешены вовремя. Таким образом, он возвращается как можно скорее.источник
Использование AngularJS 1.1.5
Обновление функции «телефоны» в ответе Джустена с использованием синтаксиса AngularJS 1.1.5 .
Оригинал:
Обновлено:
Гораздо короче благодаря команде Angular и авторам. :)
Это также ответ Максимилиана Гофмана. Видимо, этот коммит сделал это в 1.1.5.
источник
$promise
в документах . Это могло быть удалено с v2.0 +.Можно использовать свойство разрешения $ routeProvider, чтобы отложить изменение маршрута до загрузки данных.
Обратите внимание, что
resolve
свойство определено на маршруте.EntitiesCtrlResolve
иEntityCtrlResolve
это постоянные объекты , определенные в том же файле , какEntitiesCtrl
иEntityCtrl
контроллеры.источник
Мне нравится идея darkporter, потому что команде разработчиков, новичкам в AngularJS, будет легко понять и сразу начать работать.
Я создал эту адаптацию, которая использует 2 div, один для панели загрузчика, а другой для фактического контента, отображаемого после загрузки данных. Обработка ошибок будет сделана в другом месте.
Добавьте флаг 'ready' в $ scope:
В виде HTML:
Смотрите также: документы с индикатором выполнения Boostrap
источник
Мне понравились приведенные выше ответы и я многому научился у них, но в большинстве приведенных выше ответов чего-то не хватает.
Я застрял в похожем сценарии, где я решал URL с некоторыми данными, которые выбираются в первом запросе с сервера. Проблема, с которой я столкнулся, заключалась в том, что если обещание будет
rejected
.Я использую пользовательский поставщик , который используется для возврата ,
Promise
который разрешилсяresolve
в$routeProvider
то время фазы конфигурации.Здесь я хочу подчеркнуть, что концепция
when
делает что-то вроде этого.Он видит URL-адрес в строке URL-адреса, а затем соответствующий
when
блок в вызываемом контроллере, и просмотр до сих пор считается хорошим.Допустим, у меня есть следующий код фазы конфигурации.
По корневому URL в браузере вызывается первый блок запуска, иначе
otherwise
вызывается.Давайте представим сценарий, который я нажал на rootUrl в
AuthServicePrivider.auth()
функции адресной строки .Допустим, обещание вернулось в состоянии отказа, что тогда ???
Ничего не делается вообще.
Otherwise
блок не будет выполняться так, как это делается для любого URL, который не определен в блоке конфигурации и неизвестен на этапе конфигурации angularJs.Нам придется обработать событие, которое запускается, когда это обещание не выполнено. При неудаче
$routeChangeErorr
увольняют$rootScope
.Это может быть зафиксировано, как показано в коде ниже.
IMO Как правило, рекомендуется помещать код отслеживания событий в блок запуска приложения. Этот код запускается сразу после этапа настройки приложения.
Таким образом, мы можем справиться с ошибкой обещания во время фазы конфигурации.
источник
У меня был сложный многоуровневый интерфейс скользящей панели с отключенным слоем экрана. Создание директивы по отключению слоя экрана, которая создала бы событие щелчка, чтобы выполнить состояние как
производили потрясающий эффект. history.back () вместо этого работала нормально, однако в моем случае это не всегда возвращается в историю. Итак, я обнаружил, что если я просто создаю атрибут href на своем экране отключения вместо state.go, это работает как чудо.
Директива «назад»
app.js я просто сохраняю предыдущее состояние
источник
Одним из возможных решений может быть использование директивы ng-cloak с элементом, в котором мы используем модели, например
Я думаю, что это требует минимум усилий.
источник