Angularjs 如何从$http调用设置变量,然后在应用程序的其余部分使用它,而不使整个应用程序异步

Angularjs 如何从$http调用设置变量,然后在应用程序的其余部分使用它,而不使整个应用程序异步,angularjs,Angularjs,我有这些数据 { "config": { "RESTAPIURL": "http://myserver/myrestsite" } } 我有一个工厂可以读取数据 'use strict'; angular.module('myApp').factory('api', ["$http", "$q", function ($http, $q) { function _getConfiguration() { var deferred = $q.def

我有这些数据

{
  "config": {
    "RESTAPIURL": "http://myserver/myrestsite"
  }
}
我有一个工厂可以读取数据

'use strict';

angular.module('myApp').factory('api',
  ["$http", "$q",
  function ($http, $q) {

    function _getConfiguration() {
      var deferred = $q.defer();
      $http.get('/scripts/constants/config.json')
      .success(function (data) {
        deferred.resolve(data);
      })
      .error(function (data, status) {
        deferred.reject(data, status);
      });
      return deferred.promise;
    }

    function _restApiUrl() {
      // this doesn't work either. _getConfiguration() doesn't resolve here.
      return _getConfiguration().RESTAPIURL + '/api/';
    }

    return {
      URL: _restApiUrl
    }
  }
  ]
);
然后使用它

'use strict';

angular.module('myApp').factory('AuthService', function ($http, $q, api,NotificationService) {

    function _get(creds) {

        var deferred = $q.defer();

        $http({method: 'GET', url: api.URL() + api.AUTH, headers: {
            'Authorization': 'Basic '+creds}
        })
        .success(function (data, status, results, headers) {
            deferred.resolve(results);
        })
        .error(function (data, status) {
            NotificationService.redirect(status);
            deferred.reject(data, status);
        });
        return deferred.promise;
    }

    return {
        get:_get
    };
});
因此,当我使用它时,我正在执行
api.URL()
,但它不起作用

它以前是硬编码的URL,所以调用它以前是
api.URL
。我真的不想浏览整个应用程序并将所有内容转换为
api.URL()。然后(…)
。那太糟糕了

那么,我如何将这个值确定为一个“属性”,而不是一个必须反复调用的异步承诺呢

打一次电话,好的。获取值。把它放在某个地方。使用该值。以后不要再调用
$http

编辑


这是我问过的最成功的问题之一,我很感激地依次阅读每一个答案。谢谢大家。

我会将回调传递给getURL方法,并在返回时保存URL。然后,我会将任何后续请求附加到该回调。在这里,我假设您正在使用
api.AUTH
执行类似的操作,而您的代码中没有引用该操作

将回调传递给
api
服务中的
getURL
方法

angular.module('myApp').factory('api', ["$http", "$q",

function ($http, $q) {

    function _getConfiguration() {
        var deferred = $q.defer();
        $http.get('/scripts/constants/config.json')
            .success(function (data) {
            deferred.resolve(data);
        })
            .error(function (data, status) {
            deferred.reject(data, status);
        });
        return deferred.promise;
    }

    return {
        getURL: function (cb) {
            var that = this;
            if (that.URL) {
                return cb(that.URL);
            }

            _.getConfiguration().then(function (data) {
                that.URL = data.config.RESTAPIURL + "/api";
                cb(that.URL);
            });
        }
    }
}]);
在您的
AuthService
中,将您的
\u get
包装在回调中,如下所示:

angular.module('myApp').factory('AuthService', function ($http, $q, api, NotificationService) {

    function _get(creds) {
        var deferred = $q.defer();
        var getCallback = function (url) {

            $http({
                method: 'GET',
                url: url + api.AUTH,
                headers: {
                    'Authorization': 'Basic ' + creds
                }
            })
                .success(function (data, status, results, headers) {
                deferred.resolve(results);
            })
                .error(function (data, status) {
                NotificationService.redirect(status);
                deferred.reject(data, status);
            });
        };
        api.getURL(getCallback);
        return deferred.promise;
    }

    return {
        get: _get
    };
});

我将向getURL方法传递回调,并在返回时保存URL。然后,我会将任何后续请求附加到该回调。在这里,我假设您正在使用
api.AUTH
执行类似的操作,而您的代码中没有引用该操作

将回调传递给
api
服务中的
getURL
方法

angular.module('myApp').factory('api', ["$http", "$q",

function ($http, $q) {

    function _getConfiguration() {
        var deferred = $q.defer();
        $http.get('/scripts/constants/config.json')
            .success(function (data) {
            deferred.resolve(data);
        })
            .error(function (data, status) {
            deferred.reject(data, status);
        });
        return deferred.promise;
    }

    return {
        getURL: function (cb) {
            var that = this;
            if (that.URL) {
                return cb(that.URL);
            }

            _.getConfiguration().then(function (data) {
                that.URL = data.config.RESTAPIURL + "/api";
                cb(that.URL);
            });
        }
    }
}]);
在您的
AuthService
中,将您的
\u get
包装在回调中,如下所示:

angular.module('myApp').factory('AuthService', function ($http, $q, api, NotificationService) {

    function _get(creds) {
        var deferred = $q.defer();
        var getCallback = function (url) {

            $http({
                method: 'GET',
                url: url + api.AUTH,
                headers: {
                    'Authorization': 'Basic ' + creds
                }
            })
                .success(function (data, status, results, headers) {
                deferred.resolve(results);
            })
                .error(function (data, status) {
                NotificationService.redirect(status);
                deferred.reject(data, status);
            });
        };
        api.getURL(getCallback);
        return deferred.promise;
    }

    return {
        get: _get
    };
});

为什么不在应用程序加载时初始化工厂并将变量放到另一个属性上?大概是这样的:

angular.module('myApp').factory('api', ["$http", "$q",
  function ($http, $q) {
    // store URL in a variable within the factory
    var _URL;

    function _initFactory() {
      var deferred = $q.defer();
      $http.get('/scripts/constants/config.json')
      .success(function (data) {

        // Set your variable after the data is received
        _URL = data.RESTAPIURL;
        deferred.resolve(data);

      });
      return deferred.promise;
    }

    function getURL() {
        return _URL;
    }

    return {
      initFactory: _initFactory,
      URL: getURL
    }
  }
  ]
);


// While the app is initializing a main controller, or w/e you may do, run initFactory
//...
api.initFactory().then(
  // may not need to do this if the URL isn't used during other initialization
)
//...

// then to use the variable later
function _get(creds) {

    var deferred = $q.defer();

    $http({method: 'GET', url: api.URL + api.AUTH, headers: {
        'Authorization': 'Basic '+creds}
    })
    .success(function (data, status, results, headers) {
        deferred.resolve(results);
    })
    return deferred.promise;
 }

为什么不在应用程序加载时初始化工厂并将变量放到另一个属性上?大概是这样的:

angular.module('myApp').factory('api', ["$http", "$q",
  function ($http, $q) {
    // store URL in a variable within the factory
    var _URL;

    function _initFactory() {
      var deferred = $q.defer();
      $http.get('/scripts/constants/config.json')
      .success(function (data) {

        // Set your variable after the data is received
        _URL = data.RESTAPIURL;
        deferred.resolve(data);

      });
      return deferred.promise;
    }

    function getURL() {
        return _URL;
    }

    return {
      initFactory: _initFactory,
      URL: getURL
    }
  }
  ]
);


// While the app is initializing a main controller, or w/e you may do, run initFactory
//...
api.initFactory().then(
  // may not need to do this if the URL isn't used during other initialization
)
//...

// then to use the variable later
function _get(creds) {

    var deferred = $q.defer();

    $http({method: 'GET', url: api.URL + api.AUTH, headers: {
        'Authorization': 'Basic '+creds}
    })
    .success(function (data, status, results, headers) {
        deferred.resolve(results);
    })
    return deferred.promise;
 }

我知道您没有使用此处的任何$resource,但我希望您对它们有很好的了解:

工厂/delay resource.js中:

'use strict'

angular.module('myApp').factory('delayResource', ['$resource', '$q',
function($resource, $q){
    var _methods = ['query', 'get', 'delete', 'remove', 'save'];

    var shallowClearAndCopy = function(src, dst) {
            dst = dst || {};

            angular.forEach(dst, function(value, key){
                delete dst[key];
            });

            for (var key in src) {
                if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
                    dst[key] = src[key];
                }
            }

            return dst;
        }

    var delayResourceFactory = function(baseUrlPromise, url, paramDefaults){
        var _baseUrlPromise = baseUrlPromise,
            _url = url,
            _paramDefaults = paramDefaults;

        var DelayResource = function(value){
            shallowClearAndCopy(value || {}, this);
        };

        _methods.forEach(function(method){
            DelayResource[method] = function(params, successCB, errCB, progressCB){
                if (angular.isFunction(params)) {
                    progressCB = successCB;
                    errCB = errHandlers;
                    successCB = params;
                    errHandlers = params = null;
                }
                else if (!params || angular.isFunction(params)){
                    progressCB = errCB;
                    errCB = successCB;
                    successCB = errHandlers;
                    params = {};
                }

                var _makeResultResource = function(url){
                    var promise = $resource(url, _paramDefaults)[method](params);

                        (promise.$promise || promise).then(
                            function successHandler(){
                                var data = arguments[0];

                                if (isInstance){
                                    if (angular.isArray(data))
                                        for (var i = 0; i < data.length; i++)
                                            data[i] = new DelayResource(data[i])
                                    else if (angular.isObject(data))
                                        data = new DelayResource(data)
                                }

                                successCB.apply(successCB, arguments)
                                resultDelay.resolve.apply(resultDelay.resolve, arguments)
                            },
                            function(err){
                                errCB.apply(errCB, arguments)
                                resultDelay.reject.apply(resultDelay.reject, args)
                            },
                            function(){
                                progressCB.apply(progressCB, arguments)
                                resultDelay.notify.apply(resultDelay.notify, arguments)
                            }
                        )
                }

                var isInstance = this instanceof DelayResource,
                    resultDelay = $q.defer();

                if (!angular.isString(_baseUrlPromise) && angular.isFunction(_baseUrlPromise.then))
                    _baseUrlPromise.then(
                        function successCb(apiObj){
                            _makeResultResource(apiObj.RESTAPIURL + _url)
                        },
                        function successCb(){
                            throw 'ERROR - ' + JSON.stringify(arguments, null, 4)
                        })
                else
                    _makeResultResource(_baseUrlPromise.RESTAPIURL + _url);

                return resultDelay.promise;
            };


            DelayResource.prototype['$' + method] = function(){
                var value = DelayResource[method].apply(DelayResource[method], arguments);
                return value.$promise || value;
            }
        });

        return DelayResource;
    }

    return delayResourceFactory;
}]);
angular.module('myApp').factory('apiResource', ['delayResource', 'api', function (delayResource, api) {
    return function (url, params) {
        return delayResource(api.URL(), url, params);
    };
}])
'use strict';

angular.module('myApp').factory('AuthService', ['$q', 'AuthRoute', 'NotificationService', function ($q, AuthRoute, api, NotificationService) {
    function _get(creds) {
        var deferred = $q.defer();

        AuthRoute.get()
            .then(
                function successCb(results){
                    deferred.resolve(results);
                },
                function errCb(){
                    // cant remember what comes into this function
                    // but handle your error appropriately here

                    //NotificationService.redirect(status);
                    //deferred.reject(data, status);
                }
            );

        return deferred.promise;
    }

    return {
        get:_get
    };
}]);
现在,所有创建的工厂只需调用apiResource即可获得与RESTAPI通信的资源的句柄

然后在类似于工厂/account factory.js的文件中

angular.module('myApp').factory('AuthRoute', ['apiResource', 'api', function (apiResource, api) {
     return apiResource(api.AUTH);
}]);
现在在工厂/auth service.js中:

'use strict'

angular.module('myApp').factory('delayResource', ['$resource', '$q',
function($resource, $q){
    var _methods = ['query', 'get', 'delete', 'remove', 'save'];

    var shallowClearAndCopy = function(src, dst) {
            dst = dst || {};

            angular.forEach(dst, function(value, key){
                delete dst[key];
            });

            for (var key in src) {
                if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
                    dst[key] = src[key];
                }
            }

            return dst;
        }

    var delayResourceFactory = function(baseUrlPromise, url, paramDefaults){
        var _baseUrlPromise = baseUrlPromise,
            _url = url,
            _paramDefaults = paramDefaults;

        var DelayResource = function(value){
            shallowClearAndCopy(value || {}, this);
        };

        _methods.forEach(function(method){
            DelayResource[method] = function(params, successCB, errCB, progressCB){
                if (angular.isFunction(params)) {
                    progressCB = successCB;
                    errCB = errHandlers;
                    successCB = params;
                    errHandlers = params = null;
                }
                else if (!params || angular.isFunction(params)){
                    progressCB = errCB;
                    errCB = successCB;
                    successCB = errHandlers;
                    params = {};
                }

                var _makeResultResource = function(url){
                    var promise = $resource(url, _paramDefaults)[method](params);

                        (promise.$promise || promise).then(
                            function successHandler(){
                                var data = arguments[0];

                                if (isInstance){
                                    if (angular.isArray(data))
                                        for (var i = 0; i < data.length; i++)
                                            data[i] = new DelayResource(data[i])
                                    else if (angular.isObject(data))
                                        data = new DelayResource(data)
                                }

                                successCB.apply(successCB, arguments)
                                resultDelay.resolve.apply(resultDelay.resolve, arguments)
                            },
                            function(err){
                                errCB.apply(errCB, arguments)
                                resultDelay.reject.apply(resultDelay.reject, args)
                            },
                            function(){
                                progressCB.apply(progressCB, arguments)
                                resultDelay.notify.apply(resultDelay.notify, arguments)
                            }
                        )
                }

                var isInstance = this instanceof DelayResource,
                    resultDelay = $q.defer();

                if (!angular.isString(_baseUrlPromise) && angular.isFunction(_baseUrlPromise.then))
                    _baseUrlPromise.then(
                        function successCb(apiObj){
                            _makeResultResource(apiObj.RESTAPIURL + _url)
                        },
                        function successCb(){
                            throw 'ERROR - ' + JSON.stringify(arguments, null, 4)
                        })
                else
                    _makeResultResource(_baseUrlPromise.RESTAPIURL + _url);

                return resultDelay.promise;
            };


            DelayResource.prototype['$' + method] = function(){
                var value = DelayResource[method].apply(DelayResource[method], arguments);
                return value.$promise || value;
            }
        });

        return DelayResource;
    }

    return delayResourceFactory;
}]);
angular.module('myApp').factory('apiResource', ['delayResource', 'api', function (delayResource, api) {
    return function (url, params) {
        return delayResource(api.URL(), url, params);
    };
}])
'use strict';

angular.module('myApp').factory('AuthService', ['$q', 'AuthRoute', 'NotificationService', function ($q, AuthRoute, api, NotificationService) {
    function _get(creds) {
        var deferred = $q.defer();

        AuthRoute.get()
            .then(
                function successCb(results){
                    deferred.resolve(results);
                },
                function errCb(){
                    // cant remember what comes into this function
                    // but handle your error appropriately here

                    //NotificationService.redirect(status);
                    //deferred.reject(data, status);
                }
            );

        return deferred.promise;
    }

    return {
        get:_get
    };
}]);
你可以想象,我还没有能够测试它,但这是基础。我将尝试创建一个场景,让我能够测试这一点。同时,可以自由提问或指出错误

后期添加 忘记添加以下内容:

'use strict';

angular.module('myApp').factory('api', ["$http", "$q", function ($http, $q) {
  var restApiObj,
      promise;

  function _getConfiguration() {
    if (restApiObj)
      return restApiObj;

    if (promise)
      return promise;

    promise = $http.get('/scripts/constants/config.json')
        .then(function (data) {
          restApiObj = data;
          promise = null;
          return data;
        },
        function (data, status) {
          restApiObj = null;
          promise = null;
        });
    return promise;
  }

  return {
    URL: _getConfiguration
  }
}]);
继续ui路由器场景

.state('member-list', {
    url: '/members?limit=&skip='
    templateUrl: '/views/members/list.html',
    controller: 'MemberListCtrl',
    resolve:{
      members: ['$stateParams', 'MembersLoader', function($stateParams,MembersLoader){
        return MembersLoader({skip: $stateParams.skip || 0, limit: $stateParams.limit || 10});
      }       
    }
 });
工厂

.factory('MemberRoute', ['apiResource', function(apiResource){
    return apiResource('/members/:id', { id: '@id' });
}])
.factory('MembersLoader', ['MembersRoute', function(MembersRoute){
    return function(params){
        return MemberRoute.query(params);
    };
}])
.factory('MemberFollowRoute', ['apiResource', 'api', function(apiResource, api){
    return apiResource(api.FOLLOW_MEMBER, { id: '@id' });
}])
控制器

.controller('MemberListCtrl', ['$scope', 'members', 'MemberRoute', 'MemberFollowRoute', function($scope, members, MemberRoute, MemberFollowRoute){
    $scope.members = members;

    $scope.followMember = function(memberId){
        MemberFollowRoute.save(
            { id: memberId },
            function successCb(){
                //Handle your success, possibly with notificationService
            },
            function errCb(){
                // error, something happened that doesn't allow you to follow memberId
                //handle this, possibly with notificationService
            }
        )
    };

    $scope.unfollowMember = function(memberId){
        MemberFollowRoute.delete(
            { id: memberId },
            function successCb(){
                //Handle your success, possibly with notificationService
            },
            function errCb(){
                // error, something happened that doesn't allow you to unfollow memberId
                //handle this, possibly with notificationService
            }
        )
    };
}]);
有了上面的所有代码,您将永远不需要在应用程序启动时或在某些抽象根状态下进行任何类型的初始化。如果每5分钟销毁一次API配置,则无需手动重新初始化该对象,并希望在再次获取配置时,某个对象不忙或不需要它


此外,如果您查看MembersRoute工厂,apiResource会抽象/模糊您希望不必到处更改的api.URL()。现在,您只需提供您想要请求的url(例如:/members/:id或api.AUTH),就不必再担心api.url())

我知道您没有使用任何$resource,但我希望您对它们有很好的了解:

工厂/delay resource.js中:

'use strict'

angular.module('myApp').factory('delayResource', ['$resource', '$q',
function($resource, $q){
    var _methods = ['query', 'get', 'delete', 'remove', 'save'];

    var shallowClearAndCopy = function(src, dst) {
            dst = dst || {};

            angular.forEach(dst, function(value, key){
                delete dst[key];
            });

            for (var key in src) {
                if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
                    dst[key] = src[key];
                }
            }

            return dst;
        }

    var delayResourceFactory = function(baseUrlPromise, url, paramDefaults){
        var _baseUrlPromise = baseUrlPromise,
            _url = url,
            _paramDefaults = paramDefaults;

        var DelayResource = function(value){
            shallowClearAndCopy(value || {}, this);
        };

        _methods.forEach(function(method){
            DelayResource[method] = function(params, successCB, errCB, progressCB){
                if (angular.isFunction(params)) {
                    progressCB = successCB;
                    errCB = errHandlers;
                    successCB = params;
                    errHandlers = params = null;
                }
                else if (!params || angular.isFunction(params)){
                    progressCB = errCB;
                    errCB = successCB;
                    successCB = errHandlers;
                    params = {};
                }

                var _makeResultResource = function(url){
                    var promise = $resource(url, _paramDefaults)[method](params);

                        (promise.$promise || promise).then(
                            function successHandler(){
                                var data = arguments[0];

                                if (isInstance){
                                    if (angular.isArray(data))
                                        for (var i = 0; i < data.length; i++)
                                            data[i] = new DelayResource(data[i])
                                    else if (angular.isObject(data))
                                        data = new DelayResource(data)
                                }

                                successCB.apply(successCB, arguments)
                                resultDelay.resolve.apply(resultDelay.resolve, arguments)
                            },
                            function(err){
                                errCB.apply(errCB, arguments)
                                resultDelay.reject.apply(resultDelay.reject, args)
                            },
                            function(){
                                progressCB.apply(progressCB, arguments)
                                resultDelay.notify.apply(resultDelay.notify, arguments)
                            }
                        )
                }

                var isInstance = this instanceof DelayResource,
                    resultDelay = $q.defer();

                if (!angular.isString(_baseUrlPromise) && angular.isFunction(_baseUrlPromise.then))
                    _baseUrlPromise.then(
                        function successCb(apiObj){
                            _makeResultResource(apiObj.RESTAPIURL + _url)
                        },
                        function successCb(){
                            throw 'ERROR - ' + JSON.stringify(arguments, null, 4)
                        })
                else
                    _makeResultResource(_baseUrlPromise.RESTAPIURL + _url);

                return resultDelay.promise;
            };


            DelayResource.prototype['$' + method] = function(){
                var value = DelayResource[method].apply(DelayResource[method], arguments);
                return value.$promise || value;
            }
        });

        return DelayResource;
    }

    return delayResourceFactory;
}]);
angular.module('myApp').factory('apiResource', ['delayResource', 'api', function (delayResource, api) {
    return function (url, params) {
        return delayResource(api.URL(), url, params);
    };
}])
'use strict';

angular.module('myApp').factory('AuthService', ['$q', 'AuthRoute', 'NotificationService', function ($q, AuthRoute, api, NotificationService) {
    function _get(creds) {
        var deferred = $q.defer();

        AuthRoute.get()
            .then(
                function successCb(results){
                    deferred.resolve(results);
                },
                function errCb(){
                    // cant remember what comes into this function
                    // but handle your error appropriately here

                    //NotificationService.redirect(status);
                    //deferred.reject(data, status);
                }
            );

        return deferred.promise;
    }

    return {
        get:_get
    };
}]);
现在,所有创建的工厂只需调用apiResource即可获得与RESTAPI通信的资源的句柄

然后在类似于工厂/account factory.js的文件中

angular.module('myApp').factory('AuthRoute', ['apiResource', 'api', function (apiResource, api) {
     return apiResource(api.AUTH);
}]);
现在在工厂/auth service.js中:

'use strict'

angular.module('myApp').factory('delayResource', ['$resource', '$q',
function($resource, $q){
    var _methods = ['query', 'get', 'delete', 'remove', 'save'];

    var shallowClearAndCopy = function(src, dst) {
            dst = dst || {};

            angular.forEach(dst, function(value, key){
                delete dst[key];
            });

            for (var key in src) {
                if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
                    dst[key] = src[key];
                }
            }

            return dst;
        }

    var delayResourceFactory = function(baseUrlPromise, url, paramDefaults){
        var _baseUrlPromise = baseUrlPromise,
            _url = url,
            _paramDefaults = paramDefaults;

        var DelayResource = function(value){
            shallowClearAndCopy(value || {}, this);
        };

        _methods.forEach(function(method){
            DelayResource[method] = function(params, successCB, errCB, progressCB){
                if (angular.isFunction(params)) {
                    progressCB = successCB;
                    errCB = errHandlers;
                    successCB = params;
                    errHandlers = params = null;
                }
                else if (!params || angular.isFunction(params)){
                    progressCB = errCB;
                    errCB = successCB;
                    successCB = errHandlers;
                    params = {};
                }

                var _makeResultResource = function(url){
                    var promise = $resource(url, _paramDefaults)[method](params);

                        (promise.$promise || promise).then(
                            function successHandler(){
                                var data = arguments[0];

                                if (isInstance){
                                    if (angular.isArray(data))
                                        for (var i = 0; i < data.length; i++)
                                            data[i] = new DelayResource(data[i])
                                    else if (angular.isObject(data))
                                        data = new DelayResource(data)
                                }

                                successCB.apply(successCB, arguments)
                                resultDelay.resolve.apply(resultDelay.resolve, arguments)
                            },
                            function(err){
                                errCB.apply(errCB, arguments)
                                resultDelay.reject.apply(resultDelay.reject, args)
                            },
                            function(){
                                progressCB.apply(progressCB, arguments)
                                resultDelay.notify.apply(resultDelay.notify, arguments)
                            }
                        )
                }

                var isInstance = this instanceof DelayResource,
                    resultDelay = $q.defer();

                if (!angular.isString(_baseUrlPromise) && angular.isFunction(_baseUrlPromise.then))
                    _baseUrlPromise.then(
                        function successCb(apiObj){
                            _makeResultResource(apiObj.RESTAPIURL + _url)
                        },
                        function successCb(){
                            throw 'ERROR - ' + JSON.stringify(arguments, null, 4)
                        })
                else
                    _makeResultResource(_baseUrlPromise.RESTAPIURL + _url);

                return resultDelay.promise;
            };


            DelayResource.prototype['$' + method] = function(){
                var value = DelayResource[method].apply(DelayResource[method], arguments);
                return value.$promise || value;
            }
        });

        return DelayResource;
    }

    return delayResourceFactory;
}]);
angular.module('myApp').factory('apiResource', ['delayResource', 'api', function (delayResource, api) {
    return function (url, params) {
        return delayResource(api.URL(), url, params);
    };
}])
'use strict';

angular.module('myApp').factory('AuthService', ['$q', 'AuthRoute', 'NotificationService', function ($q, AuthRoute, api, NotificationService) {
    function _get(creds) {
        var deferred = $q.defer();

        AuthRoute.get()
            .then(
                function successCb(results){
                    deferred.resolve(results);
                },
                function errCb(){
                    // cant remember what comes into this function
                    // but handle your error appropriately here

                    //NotificationService.redirect(status);
                    //deferred.reject(data, status);
                }
            );

        return deferred.promise;
    }

    return {
        get:_get
    };
}]);
你可以想象,我还没有能够测试它,但这是基础。我将尝试创建一个场景,让我能够测试这一点。同时,可以自由提问或指出错误

后期添加 忘记添加以下内容:

'use strict';

angular.module('myApp').factory('api', ["$http", "$q", function ($http, $q) {
  var restApiObj,
      promise;

  function _getConfiguration() {
    if (restApiObj)
      return restApiObj;

    if (promise)
      return promise;

    promise = $http.get('/scripts/constants/config.json')
        .then(function (data) {
          restApiObj = data;
          promise = null;
          return data;
        },
        function (data, status) {
          restApiObj = null;
          promise = null;
        });
    return promise;
  }

  return {
    URL: _getConfiguration
  }
}]);
继续ui路由器场景

.state('member-list', {
    url: '/members?limit=&skip='
    templateUrl: '/views/members/list.html',
    controller: 'MemberListCtrl',
    resolve:{
      members: ['$stateParams', 'MembersLoader', function($stateParams,MembersLoader){
        return MembersLoader({skip: $stateParams.skip || 0, limit: $stateParams.limit || 10});
      }       
    }
 });
工厂

.factory('MemberRoute', ['apiResource', function(apiResource){
    return apiResource('/members/:id', { id: '@id' });
}])
.factory('MembersLoader', ['MembersRoute', function(MembersRoute){
    return function(params){
        return MemberRoute.query(params);
    };
}])
.factory('MemberFollowRoute', ['apiResource', 'api', function(apiResource, api){
    return apiResource(api.FOLLOW_MEMBER, { id: '@id' });
}])
控制器

.controller('MemberListCtrl', ['$scope', 'members', 'MemberRoute', 'MemberFollowRoute', function($scope, members, MemberRoute, MemberFollowRoute){
    $scope.members = members;

    $scope.followMember = function(memberId){
        MemberFollowRoute.save(
            { id: memberId },
            function successCb(){
                //Handle your success, possibly with notificationService
            },
            function errCb(){
                // error, something happened that doesn't allow you to follow memberId
                //handle this, possibly with notificationService
            }
        )
    };

    $scope.unfollowMember = function(memberId){
        MemberFollowRoute.delete(
            { id: memberId },
            function successCb(){
                //Handle your success, possibly with notificationService
            },
            function errCb(){
                // error, something happened that doesn't allow you to unfollow memberId
                //handle this, possibly with notificationService
            }
        )
    };
}]);
有了上面的所有代码,您将永远不需要在应用程序启动时或在某些抽象根状态下进行任何类型的初始化。如果每5分钟销毁一次API配置,则无需手动重新初始化该对象,并希望在再次获取配置时,某个对象不忙或不需要它


此外,如果您查看MembersRoute工厂,apiResource会抽象/模糊您希望不必到处更改的api.URL()。因此,现在,您只需提供您想要向其发出请求的url(例如:/members/:id或api.AUTH),就不必再担心api.url())

为@ThinkingMedia在评论中所说的添加了一点内容,在定义控制器时,您可以使用
ui-router
添加一个
resolve
参数

在其中,您可以指定在实例化控制器之前要解决的一些承诺,因此您始终可以确保配置对象可用于控制器或控制器正在使用的其他服务

您还可以在
ui路由器中拥有父/子控制器
,这样您就可以拥有解析配置对象的
RootController
,以及从RootController继承的所有其他控制器

.state('root', {
    abstract: true,
    template: '<ui-view></ui-view>',
    controller: 'RootController',
    resolve:{
      config: ['api', function(api){
        return api.initialize();
      }       
    }
  });

为@ThinkingMedia在评论中所说的添加了一点内容,在定义控制器时,可以使用
ui路由器
添加
resolve
参数。