Angular.js задержка инициализации контроллера

Я хотел бы отложить инициализацию контроллера до тех пор, пока необходимые данные не поступят с сервера.

Я нашел это решение для Angular 1.0.1: Отмена изменения маршрута AngularJS до загрузки модели, чтобы предотвратить мерцание, но не смог заставить его работать с Angular 1.1.0

Шаблон

<script type="text/ng-template" id="/editor-tpl.html">
Editor Template {{datasets}}
</script>
    <div ng-view>
</div>

JavaScript

function MyCtrl($scope) {    
    $scope.datasets = "initial value";
}

MyCtrl.resolve = {
    datasets : function($q, $http, $location) {
        var deferred = $q.defer();

        //use setTimeout instead of $http.get to simulate waiting for reply from server
        setTimeout(function(){
            console.log("whatever");
            deferred.resolve("updated value");
        }, 2000);

        return deferred.promise;
    }
};

var myApp = angular.module('myApp', [], function($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: '/editor-tpl.html',
        controller: MyCtrl,
        resolve: MyCtrl.resolve
    });
});​

http://jsfiddle.net/dTJ9N/1/

Ответы

Ответ 1

Так как $http возвращает обещание, это удар производительности, чтобы создать свой собственный отложенный только для того, чтобы вернуть обещание, когда приходят данные http. Вы должны уметь:

MyCtrl.resolve = {
    datasets: function ($http) {
        return $http({method: 'GET', url: '/someUrl'});
    }
};

Если вам нужно выполнить некоторую обработку результата, используйте .then, и ваше обещание закодировано бесплатно:

MyCtrl.resolve = {
    datasets: function ($http) {
        return $http({method: 'GET', url: '/someUrl'})
               .then (function (data) {
                   return frob (data);
               });
    }
};

Ответ 2

Вы всегда можете просто поместить "ng-show" в самый внешний элемент DOM и установить его равным данным, которые вы хотите подождать.

В примере, приведенном на домашней странице Angular JS, вы можете видеть, насколько это просто: http://plnkr.co/CQu8QB94Ra687IK6KgHn Все, что нужно было сделать, это Таким образом, форма не будет отображаться до тех пор, пока это значение не будет установлено.

Гораздо более интуитивно понятный и менее эффективный способ работы.

Ответ 3

Вы можете взглянуть на почти идентичный вопрос здесь, который использует ресурсы, но он работает одинаково с $http. Я думаю, что это должно работать

function MyCtrl($scope, datasets) {    
    $scope.datasets = datasets;
}

MyCtrl.resolve = {
    datasets: function($http, $q) {
        var deferred = $q.defer();

        $http({method: 'GET', url: '/someUrl'})
            .success(function(data) {
                deferred.resolve(data)
        }

        return deferred.promise;
    }
};

var myApp = angular.module('myApp', [], function($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: '/editor-tpl.html',
        controller: MyCtrl,
        resolve: MyCtrl.resolve
    });
});​