Angularjs - 交叉控制器计算

时间:2015-04-22 16:56:02

标签: javascript jquery angularjs

我正在尝试使用Angularjs创建一个应用程序,它是一个相当大的应用程序,需要分解为多个控制器。我需要跨控制器计算。

angular.module('Cross.Controller.demo',[]);

angular.module('Cross.Controller.demo').controller('KidsCtrl', function ($scope) {
   $scope.Kids = [
    {"Name":"John", "Expense":"1000"}, 
    {"Name":"Anna", "Expense":"900"}];
});

angular.module('Cross.Controller.demo').controller('HouseCtrl', function ($scope) {
   $scope.House =  {"Category":"Utilities", "Expense":"2000"};
});

angular.module('Cross.Controller.demo').controller('ResultCtrl', function ($scope) {
   $scope.Result =  {"Category":"Total", "Expense":"2000"};
});
<!doctype html>
<html ng-app="Cross.Controller.demo">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="script.js"></script>
<body>
  <div ng-controller="KidsCtrl">
    <div ng-repeat="kid in Kids">
    {{kid.Name}}
    <input type="text" ng-model="kid.Expense">
  </div>
  </div>
  
  <div ng-controller="HouseCtrl">
    {{House.Category}}
    <input type="text" ng-model="House.Expense">
  </div>
  
  <div ng-controller="ResultCtrl">
    {{Result.Category}}
    <input type="text" ng-model="Result.Expense">
  </div>
</body>
</html>

请在此处找到我的Plunk

我想将孩子的费用和房子的费用添加到结果控制器的“Result.Expense”

3 个答案:

答案 0 :(得分:1)

将所有内容放入服务中,并为所有内容致电服务。

修改:请参阅更新的plnk。所有这些都表示,您现在需要在服务发生这些变化时通知控制器。关于在Angular中使用带有服务的观察者模式,请参阅我的回答here

angular.module('Cross.Controller.demo',[]);

angular.module('Cross.Controller.demo').factory('sharedFactory', function() {
     var kids = [
       {"Name":"John", "Expense":"1000"}, 
       {"Name":"Anna", "Expense":"900"}];

     var house = {"Category":"Utilities", "Expense":"2000"};

     var getHouse = function() {
       return house;
     }

     var getKids = function() {
       return kids;
     }

     var getTotalExpenses = function() {
        var expenses = parseInt(house.Expense);
        kids.forEach(function(kid) {
          expenses += parseInt(kid.Expense);
        });

        return {
          Category: "Total",
          Expense: expenses
        }
     }

     return {
       getHouse: getHouse,
       getKids: getKids,
       getTotalExpenses: getTotalExpenses
     }
});

angular.module('Cross.Controller.demo').controller('KidsCtrl', function ($scope, sharedFactory) {
   $scope.Kids = sharedFactory.getKids();
});

angular.module('Cross.Controller.demo').controller('HouseCtrl', function ($scope, sharedFactory) {
   $scope.House = sharedFactory.getHouse();
});

angular.module('Cross.Controller.demo').controller('ResultCtrl', function ($scope, sharedFactory) {
   $scope.Result = sharedFactory.getTotalExpenses();
});

答案 1 :(得分:0)

您最好的选择是使用服务或工厂

您可以在此处找到有关它们及其差异的更多信息:when to use a service instead of a factory

答案 2 :(得分:0)

正如其他人已经说过的,最好通过外部服务来完成。

创建了一个plunk,其中一个服务用于获取/设置,并通过$rootScope.$broadcast作为事件总线通知控制器。

请注意,我只是让它适合孩子们

reference counting

angular.module('Cross.Controller.demo',[]);

angular.module('Cross.Controller.demo').service('Results', function ($rootScope) {
   var expenses = {
     kids:0,
     house:0
   }
   
   return {
     setKidsExpenses: function(cost){ 
       expenses.kids = cost;
       $rootScope.$broadcast('updatedCosts');
     },
     addHouseExpenses: function(cost){ expenses.house += cost  },
     getExpenses: function(){ return expenses }
   }
});

angular.module('Cross.Controller.demo').controller('KidsCtrl', function ($scope, Results) {
   $scope.Kids = [
    {"Name":"John", "Expense":"1000"}, 
    {"Name":"Anna", "Expense":"900"}];
    
    $scope.$watch('Kids', function(){
      var kidsExpenses = 0;
      for(var i = 0; i < $scope.Kids.length; i++){
        kidsExpenses += parseInt($scope.Kids[i].Expense)
      }
      
      Results.setKidsExpenses(kidsExpenses)
      
    }, true)
});

angular.module('Cross.Controller.demo').controller('HouseCtrl', function ($scope) {
   $scope.House =  {"Category":"Utilities", "Expense":"2000"};
});

angular.module('Cross.Controller.demo').controller('ResultCtrl', function ($scope, Results) {

  $scope.$on('updatedCosts', function(){
    var expenses = Results.getExpenses()
    var totalExpenses = expenses.kids + expenses.house;
    $scope.Result =  {"Category":"Total", "Expense":totalExpenses};
  })
  
});
<!doctype html>
<html ng-app="Cross.Controller.demo">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="script.js"></script>
<body>
  <div ng-controller="KidsCtrl">
    <div ng-repeat="kid in Kids">
      {{kid.Name}}
      <input type="text" ng-model="kid.Expense">
    </div>
  </div>
  
  <div ng-controller="HouseCtrl">
    {{House.Category}}
    <input type="text" ng-model="House.Expense">
  </div>
  
  <div ng-controller="ResultCtrl">
    {{Result.Category}}
    <input type="text" ng-model="Result.Expense">
  </div>
</body>
</html>