AngularJS + Cloud Endpoints: загрузка API конечных точек на несколько контроллеров

Я инициализировал свое приложение, следуя этим двум руководствам:

Моя установка выглядит примерно так:

app.js

function init() {
    console.log('running global init()');
    window.initgapi();
}

var app = angular.module('app', []);

// Main Controller
app.controller('MainCtrl', ['$scope', '$window', 'cloudendpoints', function($scope, $window, cloudendpoints) {

    // this is called once eventapi is loaded
    var postInit = function() {
        $scope.backend_ready = true;
        $scope.fetchContent();
    };

    $window.initgapi = function() {
        cloudendpoints.init(postInit);
    };

    $scope.fetchContent = function() {
        gapi.client.cloudendpoints
            .getContent()
            .execute(function(resp) {
                // do something with response
            });
    };

}]);

Служба cloudendpoints находится в своем собственном файле, cloudendpoints.js:

// for loading endpoints service
app.factory('cloudendpoints', [function cloudendpoints() {
    var init = function(postInit) {
        var restUrl = '//' + window.location.host + '/_ah/api';
        gapi.client.load('cloudendpoints', 'v1', postInit, restUrl);
    };
    return { init: init };
}]);

Наконец, наши скрипты загружаются в следующем порядке:

<script src="angular.min.js"></script>
<script src="app.js"></script>
<script src="controllers/mainCtrl.js"></script>
<script src="services/cloudendpoints.js"></script>
<script src="https://apis.google.com/js/client.js?onload=init"></script>    

Проблема До сих пор это хорошо работает, потому что мы используем только один контроллер (MainCtrl). Вот что происходит в нашем коде:

  1. Клиент gapi загружается, затем вызывает init(), который вызывает window.loadCloudEndpoints()
  2. cloudendpoints.init(postInit) загружает службу конечной точки cloudendpoints, которая затем вызывает postInit() Перезвоните. Затем мы можем сделать вызовы API оконечных точек из postInit(),

Проблема возникает, когда мы хотим создать еще один контроллер для обработки другого представления нашего приложения. Допустим, мы создаем ContentPageCtrl контроллер - нужно ли нам снова запускать нашу службу конечных точек? Как мы можем сделать службу конечной точки доступной для всех контроллеров, не повторяя себя?

Мое хакерское решение Чтобы обойти это, я $watch the backend_ready так что я могу начать делать гэппи-вызовы только после загрузки конечных точек API:

 app.controller('ContentPageCtrl', ['$scope', function($scope) {

    /**
     * Make sure that the backend is ready before
     *   running any gapi.client.cloudendpoints calls
     **/
    $scope.$watch('backend_ready', function() {
        if ($scope.backend_ready === true) {
            gapi.client.cloudendpoints
                .loadContent()
                .execute(function(resp) {
                    // put content in DOM
                });
        }
    });
 }]);

Это значит, что мне нужно $watch backend_ready переменная в каждом контроллере, в котором мне нужно сделать вызовы конечной точки. Мой подход кажется довольно грязным и имеет проблемы с масштабированием.

Каков лучший подход к этому?

1 ответ

Решение

Лучшим подходом к этому было бы использование силы Promises, затем вы можете получить свой Service init один раз (внутри сервисной функции) и для каждого метода, который вы просто вызываете promise.then(...) и сохранить логику, характерную для этого метода. возьмем это в качестве примера:

app.factory('cloudendpoints', ['$q','$timeout','$window',function cloudendpoints($q,$timeout,$window) {

var backend_ready = $q.defer();

checkLoaded();
function checkLoaded(){
 if($window.gapi)
  backend_ready.resolve();
 else
  $timeout(checkLoaded,100); //check again in 100ms
}

var init = function(postInit) {
    var restUrl = '//' + window.location.host + '/_ah/api';
    return backend_ready.promise.then(function(resp){
     gapi.client.load('cloudendpoints', 'v1', postInit, restUrl);
    }); //we are returning a promise so we can have more
        //flexability inside the controllers (do stuff after the loaded api);
};
return { 
 init: init
};
}]);




//Somewhere inside a controller...
app.controller('someCtrl', ['cloudendpoints', function(cloudendpoints){
 function postInit(){ ... }


  cloudendpoints.init(postInit); //waits for gapi to load, then executes init
});
Другие вопросы по тегам