【问题标题】:Call factory only on first load仅在首次加载时调用工厂
【发布时间】:2014-12-15 10:24:00
【问题描述】:

我的控制器中有这段代码:

$scope.customers = [];
$scope.categories = [];

function init() {
   partnersFactory.getPartners(categoryId)
   .then(function(res){
      $scope.partners = res;
   },function(status){
      //err
   })

   partnersFactory.getCategories()
   .then(function(res){
      $scope.categories = res;
   },function(status){
      //err
   })
}

我需要的是在初始加载时只运行一次 partnersFactory.getCategories() ,然后将其保存不变。这样做的最佳方法是什么?使用一些变量,比如 var initialization = false 看起来不是很干净。

编辑 目的:我有一些按类别排序的数据。我现在在做什么:如果有人点击类别,我从服务器重新加载数据集,但将其过滤到类别(服务器端)。这就是为什么我需要重新加载数据,而不是类别。我做错了吗?也许最好在angularjs中过滤它? (服务器上的数据不会不断更新)。

【问题讨论】:

  • 在你的控制器函数中调用它?
  • 所以每次点击一个类别,你调用init()?
  • 我不明白,你只想在 init 上获取类别,是吗?然后用户点击某处,你只重新加载数据,不是吗?
  • 是的,在第一次加载时,我会加载类别和所有数据。如果用户点击类别,它只是过滤数据。现在我正在重新加载所有内容,并且不认为它很聪明......
  • 好的,你应该做的是创建一个加载数据的方法,另一个加载类别的方法。在初始化时,您调用这两个方法。然后在用户单击时对调用 getData() 的类别进行 ng-click。这听起来能回答你的问题吗?如果是这样,我会做一个更详细的答案;)

标签: angularjs controller factory


【解决方案1】:

怎么样:

$scope.customers = [];
$scope.categories = null;

function init() {
   partnersFactory.getPartners(categoryId)
   .then(function(res){
      $scope.partners = res;
   },function(status){
  //err
   })

   if($scope.categories == null) {
       partnersFactory.getCategories()
       .then(function(res){
          $scope.categories = res;
       },function(status){
          $scope.categories = [];
       })
    }
}

【讨论】:

  • 是的,我尝试过这种方式,但它什么也没带来,因为我每次都运行控制器并重新初始化所有内容。查看我要发布的编辑
【解决方案2】:

partnersFactory.getCategories() 放在init() 函数之外只会执行一次

所以你的控制器喜欢,

$scope.customers = [];
$scope.categories = [];

function init() {
   partnersFactory.getPartners(categoryId)
   .then(function(res){
      $scope.partners = res;
   },function(status){
      //err
   })       
}

partnersFactory.getCategories()
.then(function(res){
    $scope.categories = res;
},function(status){
      //err
})

如果您需要$scope.categories 的干净副本,请使用angular.copy(),如下所示

partnersFactory.getCategories()
.then(function(res){
    $scope.categories = res;
    $scope.originalObj = angular.copy($scope.categories); // don't do any changes to $scope.originalObj
},function(status){
      //err
})

【讨论】:

    【解决方案3】:

    所以,你需要的是这样的:

    在您的控制器中,创建 2 个方法,一个用于获取类别,另一个用于获取数据:

    angular.module('yourApp').controller('yourCtrl', ['$scope', 'yourFactory', function ($scope, yourFactory) {
    
      $scope.initPage = function () {
         $scope.getCat();
         $scope.getData();
      }
    
      $scope.getCat = function () {
         ...
      }
    
      $scope.getData = function () {
         ...
      }
    
    
      $scope.initPage();
    }]);
    

    然后在您的 html 中,在应该重新加载数据的按钮/元素上,通过 ng-click 调用您的方法

    <div>
      <button ng-click="getData"> reload </button>
    </div>
    

    当您想按类别排序时,您可以执行一些操作,例如将参数添加到 getData(category) 以精确按要过滤数据的类别,然后在您的 html 中

    <ul>
      <li ng-repeat="cat in categories"> <a ng-click="getData(cat)"> {{ cat.name }} </a> </li>
    </ul>
    

    希望对你有帮助

    【讨论】:

      【解决方案4】:

      在你的工厂里,你可以这样做:

      .factory('partnersFactory', function($http) {
          var categories = [];
      
          var getCategories = function() {
             $http.get(...)
                .success(function(data){
                   categories = data;
                });
          }
          getCategories();
      
          return {
              getPartners: function(categoryId) {
                 $http.get(...)
                    .success(onSuccess)
                    .error(onError);
              },
              getCategories: function(){
                 return categories;
              }
          };
      

      它应该兑现类别数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        • 2023-03-29
        • 2017-10-18
        • 2018-10-24
        • 1970-01-01
        • 1970-01-01
        • 2012-03-20
        相关资源
        最近更新 更多