使用 angular 工厂来保存应用程序其余部分访问的值,以最大限度地减少服务器调用
use angular factory to hold a value for rest of application to access to minimize server calls
我有以下工厂:
angularModule
.factory('ArticleCategoryService', function ($http, $q) {
// Service logic
// ...
var categories = [];
var _getCategories = $http.get('/api/articles/category').success(function (_categories) {
categories = _categories;
});
// .error( function (data, status, headers, config) {
// });
// Public API here
return {
getCategories: function () {
var deferred = $q.defer();
deferred.resolve(_getCategories);
return deferred.promise;
}
};
});
这是在控制器中调用此服务的部分:
// Calls the getCategories function from the ArticleCategory Service,
// Will return a promise
ArticleCategoryService.getCategories()
.then(function (categoriesResult) {
$scope.categories = categoriesResult.data;
}, function (err) {
console.log(err);
});
这可行,但每次用户返回此 view/state 时都会对服务器进行 GET 调用,并且从未使用属于工厂的 categories
对象。
我正在努力让它 return 工厂单例中的 categories
变量,并让它在站点加载时初始化(或从第一次 GET 调用开始)。
但是如果我只是 return categories
当用户调用 getCategories
时,它将 return 什么都没有,因为我们需要时间进行 $http
调用。
检查是否定义了 categories
,如果是,则使用变量而不是 GET
请求解析承诺:
return {
getCategories: function () {
var deferred = $q.defer();
if (categories.length > 0) {
deferred.resolve(categories);
} else {
deferred.resolve(_getCategories);
}
return deferred.promise;
}
};
angularModule
.factory('ArticleCategoryService', function ($http) {
// Service logic
// ...
var categories = [];
$http.get('/api/articles/category').success(function (_categories) {
categories = _categories;
});
// Public API here
return {
categories: categories
};
});
angularModule
.controller('ControllerMain', function($scope, ArticleCategoryService) {
$scope.categories = ArticleCategoryService.categories;
});
我在我的应用程序上做着完全相同的事情。我有一个主模块和一个包含任何其他控制器的主控制器,因此它的范围在视图上是持久的。
在这个主控制器中,您可以将工厂的 getCategory() 数据分配给范围变量,然后您可以在整个应用程序中使用它,因为范围将继承到子范围。
angularMainModule
.factory('ArticleCategoryService', function ($http) {
var ArticleCategoryServiceMethods = {};
//fn: getCategories
ArticleCategoryServiceMethods.getCategories = function(fromWhere){
return $http.get(fromWhere)
.then(function(res){
return res.data;
}, function(err){
return err.status;
});
}
return ArticleCategoryServiceMethods;
}
angularMainModule
.controller('MAINCTRL', function($scope, ArticleCategoryService) {
//get all categories
$scope.categories = ArticleCategoryService.getCategories('/api/articles/category');
//... the rest of the main ctrl code ... //
}
...当您定义主模块时,请确保将其余模块注入其中
var angularMainModule = angular.module('angularMainModule', [
'ngRoute',
'ngTouch',
'ngAnimate',
//< ng - etc >,
'Module1',
'Module2',
//< module - n >
]);
...和标记(我正在手动引导我的 angular 应用程序,但是如果您这样做的话,您可以在 html 标签上添加 ng-app="angularMainModule"
属性那样):
<html ng-controller="MAINCTRL">
<!-- head data -->
<body>
<div id="page" ng-view></div>
如果你想确保在你的应用程序打开主页之前加载数据,你可以在你的应用程序的 routeProvider
块中添加该服务调用(在默认路由上),所以当 MAINCTRL将加载数据已经存在,准备分配。
我有以下工厂:
angularModule
.factory('ArticleCategoryService', function ($http, $q) {
// Service logic
// ...
var categories = [];
var _getCategories = $http.get('/api/articles/category').success(function (_categories) {
categories = _categories;
});
// .error( function (data, status, headers, config) {
// });
// Public API here
return {
getCategories: function () {
var deferred = $q.defer();
deferred.resolve(_getCategories);
return deferred.promise;
}
};
});
这是在控制器中调用此服务的部分:
// Calls the getCategories function from the ArticleCategory Service,
// Will return a promise
ArticleCategoryService.getCategories()
.then(function (categoriesResult) {
$scope.categories = categoriesResult.data;
}, function (err) {
console.log(err);
});
这可行,但每次用户返回此 view/state 时都会对服务器进行 GET 调用,并且从未使用属于工厂的 categories
对象。
我正在努力让它 return 工厂单例中的 categories
变量,并让它在站点加载时初始化(或从第一次 GET 调用开始)。
但是如果我只是 return categories
当用户调用 getCategories
时,它将 return 什么都没有,因为我们需要时间进行 $http
调用。
检查是否定义了 categories
,如果是,则使用变量而不是 GET
请求解析承诺:
return {
getCategories: function () {
var deferred = $q.defer();
if (categories.length > 0) {
deferred.resolve(categories);
} else {
deferred.resolve(_getCategories);
}
return deferred.promise;
}
};
angularModule
.factory('ArticleCategoryService', function ($http) {
// Service logic
// ...
var categories = [];
$http.get('/api/articles/category').success(function (_categories) {
categories = _categories;
});
// Public API here
return {
categories: categories
};
});
angularModule
.controller('ControllerMain', function($scope, ArticleCategoryService) {
$scope.categories = ArticleCategoryService.categories;
});
我在我的应用程序上做着完全相同的事情。我有一个主模块和一个包含任何其他控制器的主控制器,因此它的范围在视图上是持久的。
在这个主控制器中,您可以将工厂的 getCategory() 数据分配给范围变量,然后您可以在整个应用程序中使用它,因为范围将继承到子范围。
angularMainModule
.factory('ArticleCategoryService', function ($http) {
var ArticleCategoryServiceMethods = {};
//fn: getCategories
ArticleCategoryServiceMethods.getCategories = function(fromWhere){
return $http.get(fromWhere)
.then(function(res){
return res.data;
}, function(err){
return err.status;
});
}
return ArticleCategoryServiceMethods;
}
angularMainModule
.controller('MAINCTRL', function($scope, ArticleCategoryService) {
//get all categories
$scope.categories = ArticleCategoryService.getCategories('/api/articles/category');
//... the rest of the main ctrl code ... //
}
...当您定义主模块时,请确保将其余模块注入其中
var angularMainModule = angular.module('angularMainModule', [
'ngRoute',
'ngTouch',
'ngAnimate',
//< ng - etc >,
'Module1',
'Module2',
//< module - n >
]);
...和标记(我正在手动引导我的 angular 应用程序,但是如果您这样做的话,您可以在 html 标签上添加 ng-app="angularMainModule"
属性那样):
<html ng-controller="MAINCTRL">
<!-- head data -->
<body>
<div id="page" ng-view></div>
如果你想确保在你的应用程序打开主页之前加载数据,你可以在你的应用程序的 routeProvider
块中添加该服务调用(在默认路由上),所以当 MAINCTRL将加载数据已经存在,准备分配。