无法遍历范围内的输入

Not being able to iterate through inputs within scope

我正在尝试遍历使用 angular 创建的数组,因此我可以将它们相加然后显示它们,但问题是,我收到一条错误消息说 属性 '1' of undefined 即使我填写了输入字段,这是为什么?

我的代码:

<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
  <title>jQueryForm</title>
</head>

<body ng-app="myApp" ng-controller="myCtrl">
  <div id="form" ng-init="dataSet = [{},{},{},{},{}]">
    <div ng-repeat="data in dataSet">
      <input type="checkbox" ng-model="data.checked" />
      <label>Data:</label>
      <input type="number" ng-model="data.number" />
      <br/>
    </div>

    <span>{{result}}</span>

    <script>
      var app = angular.module('myApp', []);
      app.controller('myCtrl', function($scope) {
        for (var i = 1; i < 5; i++) {
          $scope.result += $scope.dataSet[i];
        }
      });
    </script>
  </div>
  </div>
  </span>

</body>


</html>

因为 ng-init 是一种特殊的指令,它评估指令的 preLink 函数中提供给它的 expression

PreLink function: - this function gets evaluates after scope has been created for that element

通过阅读上面的行,您将了解到它在 $scope.dataset 可用之前已经评估了循环。这显然会失败。

我会说在这种情况下不要使用 ng-init。将该初始化数据放入控制器本身。

代码

//remove ng-init directive from UI
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
   function init(){
     for (var i = 1; i < 5; i++) {
       if($scope.dataSet[i].checked)
          $scope.result += $scope.dataSet[i].number;
     }
   }

   //init
   $scope.dataSet = [{},{},{},{},{}]
   init();
});

这次你必须以不同的方式初始化数据集。只需将它添加到控制器的范围而不是使用 ng-init。

<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
  <title>jQueryForm</title>
</head>

<body ng-app="myApp" ng-controller="myCtrl">
  <div id="form">
    <div ng-repeat="data in dataSet">
      <input type="checkbox" ng-model="data.checked" />
      <label>Data:</label>
      <input type="number" ng-model="data.number" />
      <br/>
    </div>

    <span>{{result}}</span>

    <script>
      var app = angular.module('myApp', []);
      app.controller('myCtrl', function($scope) {
        $scope.dataSet = [{},{},{},{},{}];

        for (var i = 1; i < 5; i++) {
          $scope.result += $scope.dataSet[i];
        }
      });
    </script>
  </div>
  </div>
  </span>

</body>


</html>

不过,要使代码正常工作,您必须进行一些更改。您尝试添加数字的循环只会被调用一次 - 在控制器的实例化时。那时,还没有输入任何数字。你可以用一个按钮来解决它。 (也是把数字加起来,不是dataSet中的对象)

<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
  <title>jQueryForm</title>
</head>

<body ng-app="myApp" ng-controller="myCtrl">
  <div id="form">
    <div ng-repeat="data in dataSet">
      <input type="checkbox" ng-model="data.checked" />
      <label>Data:</label>
      <input type="number" ng-model="data.number" />
      <br/>
    </div>

    <button ng-click="calculate()">calculate</button>
    <span>{{result}}</span>

    <script>
      var app = angular.module('myApp', []);
      app.controller('myCtrl', function($scope) {
        $scope.dataSet = [{},{},{},{},{}];

        $scope.calculate = function() {
          $scope.result = 0;

          for (var i = 0; i < $scope.dataSet.length; i++) {
            if(angular.isNumber($scope.dataSet[i].number) && $scope.dataSet[i].checked)
              $scope.result += $scope.dataSet[i].number;
          }
        };

        //Edit. Doesn't have the best performance, keep dataSet small
        $scope.$watch('dataSet', function(newValue, oldValue) {
          $scope.calculate();
        }, true);

      });
    </script>
  </div>
  </div>
  </span>

</body>


</html>

我又修复了一些问题。我假设,您只想添加那些经过检查的数字 - 此外,没有值的 ng-models 会导致问题,这就是引入数字检查的原因。

编辑: 正如您想在没有按钮的情况下这样做:您可以使用深度 $scope.$watch。 https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

感谢@Pankaj Parkar 和@JanS,我终于做了我想做的事,每次更改输入时我都会调用函数 calculate(); 并且每次单击复选框时我也会调用它。

代码:

<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
  <title>jQueryForm</title>
</head>

<body ng-app="myApp" ng-controller="myCtrl">
  <div id="form">
    <div ng-repeat="data in dataSet">
      <input ng-click="calculate()" type="checkbox" ng-model="data.checked" />
      <label>Data:</label>
      <input ng-change="calculate()" type="number" ng-model="data.number" />
      <br/>
    </div>

    <span>{{result}}</span>

    <script>
      var app = angular.module('myApp', []);
      app.controller('myCtrl', function($scope) {
        $scope.dataSet = [{}, {}, {}, {}, {}];

        $scope.calculate = function() {
          $scope.result = 0;

          for (var i = 0; i < $scope.dataSet.length; i++) {
            if (angular.isNumber($scope.dataSet[i].number) && $scope.dataSet[i].checked)
              $scope.result += $scope.dataSet[i].number;
          }
        }
      });
    </script>
  </div>
  </div>
  </span>

</body>


</html>