使用 Angular Factory 保存一个值,以便应用程序的其余部分访问,以最大程度地减少服务器调用

use angular factory to hold a value for rest of application to access to minimize server calls

本文关键字:访问 余部 服务器 调用 程度地 保存 Factory Angular 使用 一个 应用程序      更新时间:2023-09-26

我有以下工厂:

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);
      });

这有效,但每次用户返回到此视图/状态时,都会对服务器进行 GET 调用,并且永远不会使用属于工厂的categories对象。

我正在尝试这样做,以便它将在工厂单例中返回 categories 变量,并在站点加载(或从第一个 GET 调用)对其进行初始化。

但是如果我只是在用户调用getCategories时返回categories,它不会返回任何内容,因为我们需要时间进行$http调用。

检查是否定义了categories,如果定义了,则使用变量而不是GET请求解析承诺:

return {
    getCategories: function () {
        var deferred = $q.defer();
        if (categories.length > 0) {
            deferred.resolve(categories);
        } else {
            deferred.resolve(_getCategories);
        }
        return deferred.promise;
    }
};

我在我的应用程序上做同样的事情。我有一个主模块和一个主控制器,里面包装了任何其他控制器,所以它的范围在视图上是持久的。

在此主控制器中,您可以将工厂的 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 >
]);

。和标记(我正在手动引导我的角度应用程序,但如果你这样做,你可以在 HTML 标签上添加 ng-app="angularMainModule" 属性):

<html ng-controller="MAINCTRL">
<!-- head data -->
<body>
<div id="page" ng-view></div>

如果要确保在应用打开主页之前加载数据,可以在应用的routeProvider块(默认路由上)中添加该服务调用,以便在加载 MAINCTRL 时,数据将已经存在,可以分配。

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;
    });