这是我设置和获取值的基本服务:
.controller('global', ['$scope', '$http', '$api', '$location', '$translate', '$rootScope', '$timeout', '$filter', 'toastr', '$window', 'flag', 'companyService', function ($scope, $http, $api, $location, $translate, $rootScope, $timeout, $filter, toastr, $window, flag, companyService) {
$api('GetCompanyOptions', {})
.then(function (response) {
$scope.companyOptions = response.data
// doing stuff with the response first
// ...
// and setting the value to companyService
companyService.setOptions($scope.companyOptions)
})
}])
在全局控制器中,我调用我的$ api工厂,该工厂发出http请求(带有承诺)来获取和设置公司选项。我这样做只有一次。
$scope.companyOptions = companyService.options
现在几乎在每个控制器和指令中我都想使用这个值。但是因为http调用需要一段时间,我在时间上遇到了很多问题,所以有时我会得到以下的空值:(是的,在html中它自动使用$ apply和变量不是空的,但在控制器内部它是)
$scope.$watch(function () { return companyService.options }, function (newVal) {
// checking if companyService.options is still empty or not
if (!$.isEmptyObject(newVal)) {
// Now the options is filled, do some stuff...
}
})
我尝试了很多解决方案,例如使用$ watch,$ timeout,promises,$ rootScope等。但是除了在每个控制器和指令中使用$ watch之外我都没有工作:
{{1}}
所以我的问题是:
答案 0 :(得分:1)
在尝试了很多解决方案后,我认为以下最适合我。我希望它可能对其他人有用。
我决定在ngStorage(https://github.com/gsklee/ngStorage)而不是服务中持有公司选项。
所以这个:
companyService.setOptions($scope.companyOptions)
改为:
$scope.$storage.companyOptions = $scope.companyOptions
然后我在下面的代码的帮助下使用了全局路由解析,这样这段代码就可以在'之前使用。发生实际路由。 (工厂被称为checkToken,因为我也在这里做一个http请求来检查用户令牌是否有效):
Routes.config(['$routeProvider', function ($routeProvider) {
var originalWhen = $routeProvider.when
$routeProvider.when = function (path, route) {
route.resolve || (route.resolve = {})
angular.extend(route.resolve, {
checkToken: ['$checkToken', function ($checkToken) {
return $checkToken.checkToken()
}]
})
return originalWhen.call($routeProvider, path, route)
}
}])
这就是工厂本身,在那里我也会关注公司的选择。并在准备好后转到页面:
.factory('$checkToken', ['$q', '$timeout', '$location', '$api', '$rootScope', '$localStorage', function ($q, $timeout, $location, $api, $rootScope, $localStorage) {
return {
checkToken: function () {
var deferred = $q.defer()
$api('IsTokenValid', {})
.then(function (response) {
// some unrelated codes here...
// watching companyoptions in localStorage
$rootScope.$watch(function () { return $localStorage.companyOptions }, function (newVal) {
if (!$.isEmptyObject(newVal)) {
// now that we have companyOptions, resolve and go to page
deferred.resolve('go to page!')
}
}, true)
})
return deferred.promise
}
}
}])
最后,感谢这个解决方案,在我的控制器中,这个:
$scope.$watch(function () { return companyService.options }, function (newVal) {
// checking if companyService.options is still empty or not
if (!$.isEmptyObject(newVal)) {
// Now the options is filled, do some stuff...
}
})
成为这个,我摆脱了公司服务工厂:
$scope.companyOptions = $scope.$storage.companyOptions