范围属性取决于另一个范围属性?

时间:2013-06-26 11:02:05

标签: angularjs angularjs-scope

我刚开始使用Angular并且可以使用hand re:绑定到范围。

我正在尝试加载填充属性的数据。 然后我想根据这个属性更新其他属性,有没有办法轻易触发它?

目前我正在做的事情:

  1. 加载JSON数据
  2. 设置mythings
  3. 触发mythings_processed
  4. 的计算

    我觉得我应该能够用(2)触发(3)

    实施例

    的Javascript

    app.controller('MyCtrl', function($scope, $http) {
    
      $scope.loadData = function () {
        $http.get('/api/orgs/gocardless/issues.json').success(function(data) {
          $scope.mythings = data.things;
          $scope.generateCalculatedItems() // Surely this isn't necessary?
        });
      };
    
      $scope.generateCalculatedItems = function () {
        mythings_processed = {}; // Generated using mythings
        $scope.mythings_processed = mythings_processed;
      };
    };
    

    HTML

    <div ng-controller="IssuesCtrl" ng-init="loadData()">
        <ul>
          <li ng-repeat="thing in things">{{thing.id}}</li>
        </ul>
    
        <ul>
          <li ng-repeat="processed_thing in mythings_processed">{{processed_thing.id}}</li>
        </ul>
    </div>
    

    我确定我在这里对Angular做了一些可怕的事情所以我道歉!

    我觉得我应该能做到:

      $scope.mythingsProcessed = function () {
        mythings_processed = {}; // Generated using mythings
        return mythings_processed;
      };
    
       <ul>
         <li ng-repeat="processed_thing in mythingsProcessed()">{{processed_thing.id}}</li>
       </ul>
    

    但是当我这样做时,它给了我错误:10 $digest() iterations reached. Aborting!

    有什么想法吗?

    更新:示例数据/用例

    我有一个通过ajax获取的项目列表:

    {
      items: [
        {name: 'pete', value: 1},
        {name: 'john', value: 2},
        {name: 'pete', value: 3},
        {name: 'steve', value: 2},
        {name: 'john', value: 1}
      ]
    }
    

    我想显示所有这些,但我也希望将它们处理(总结)为:

    {
      processed_items: [
        { name: 'pete', value: 4 }
        { name: 'john', value: 3 }
        { name: 'steve', value: 2 }
    }
    

    然后在列表中显示这些内容。

2 个答案:

答案 0 :(得分:2)

我不是百分之百确定你想要实现的目标。但是要用(2)触发(3)你可以使用$ scope对象的watch函数:

app.controller('MyCtrl', function($scope, $http) {

  $scope.loadData = function () {
    $http.get('/api/orgs/gocardless/issues.json').success(function(data) {
      $scope.mythings = data.things;
    });
  };

  scope.$watch('mythings', function(newValue, oldValue) {
    $scope.generateCalculatedItems();
  }

  $scope.generateCalculatedItems = function () {
    mythings_processed = {}; // Generated using mythings
    $scope.mythings_processed = mythings_processed;
  };
};

要将mythings绑定到mythings_processed,你必须通过AngularJS中的$ watch-function手动进行绑定。

答案 1 :(得分:1)

通过更新后的示例,我认为问题的重点从绑定问题转移到处理传入数据的方式。这是对的吗?

我做了一个可能的解决方案: http://plnkr.co/edit/BMNmE5

一旦调用成功方法,我就会处理数据。在这种情况下不要做手表。

$scope.loadData = function() {
    $http.get('data.json').success(function(data) {
        $scope.mythings = data;
        $scope.mythingsProcessed = processThings(data);
    });
};

然后函数processThings根据需要得到总和(它使用underscore.js库):

var processThings = function(things) {
    var result = _.reduce(
        things,
        function(result, obj) {
            var storedObject = _.findWhere(result, {'name': obj.name});
            if(storedObject) {
                storedObject.value += obj.value;
                return result;
            }
            else {
                return _.union(result, _.clone(obj));
            }
        },
        []);
    return result;
};