1

各行に入力値、計算に使用される JavaScript コードの小さなブロック、および eval() が計算を実行した後の入力値の結果である小計値が含まれる JSON データセットがあります。データセットには 1 つ以上の行が含まれます。各入力は HTML でページに繰り返され、小計の合計が、個別の小計値とともに合計値としてユーザーに表示されます。

$watch を使用して、リピーターの各行に 1 つ追加しようとしましたが、ユーザーが入力値を変更すると、それらを起動できないようです。

最初のSample_Plunkerを作成して、何を達成しようとしているのかを実証しましたが、成功しませんでした。

ここにコードを投稿する必要があるかどうかはわかりませんが、助けていただければ幸いです。

基本的に私のHTML:

<div ng-controller="MainCtrl as MainCtrl" ng-init="MainCtrl.init()">
    <div ng-repeat="rule in MainCtrl.myCode">

        Input_{{$index}}: <input ng-model="rule.inpValue" type="number" />
        <!-- the following needs to reflect the result after eval() of myCode[?].code from JSON below -->
        Subtotal: {{rule.nSubTotal}}
        <br />
    </div>
    <br />

    <!-- the following should be a sum of all values above -->
    Total: {{MainCtrl.nTotal}}

</div>

これは、応答していないサンプル データと $watch です。

app.controller('MainCtrl', function($scope) {
    var _this = this;
    _this.nTotal = 0;
    // sample js code tht will be execuited later
    _this.myCode = [{
        "code": "_this.myCode.inpValue +2",
        "inpValue": 0,
        "nSubTotal": 0
    }, {
        "code": "_this.myCode.inpValue*3",
        "inpValue": 0,
        "nSubTotal": 0
    }, {
        "code": "_this.myCode.inpValue/5",
        "inpValue": 0,
        "nSubTotal": 0
    }];

    this.init = function() {
        $scope.$watch('MainCtrl.myCode[i].inpValue', function() {
            // debugger;

            // assuming if watch would fire, subtotal = eval( input ) 
            _this.nSubTotal = eval(_this.myCode[i].code);

            // I would also keep a running total at this point
            _this.nTotal = _this.nTotal + _this.myCode[i].nSubTotal;
        });
    }; //end init()
});
4

2 に答える 2

4

あなたのコードには多くの問題がありますが、基本的にあなたの質問に答えるには、配列をループして$scope.$watch要素ごとに 1 回呼び出すことで、配列内の各項目にウォッチを適用できます。

eval()また、式を評価するためではなく、実際の関数を使用することを強くお勧めします。

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

  var _this = this;
  _this.nTotal = 0;

  // sample js code tht will be execuited later
  _this.myCode = [{
    "code": function() { return this.inpValue + 2; },
    "inpValue": 0,
    "nSubTotal": 0
  }, {
    "code": function() { return this.inpValue * 3; },
    "inpValue": 0,
    "nSubTotal": 0
  }, {
    "code": function() { return this.inpValue / 5; },
    "inpValue": 0,
    "nSubTotal": 0
  }];

  function sum (values) {
      return values.reduce(function (a, b) { return a + b; }, 0);
  }

  this.init = function() {

    _this.myCode.forEach(function(code) {
      $scope.$watch(function() {
        return code.inpValue;
      }, function() {
        code.nSubTotal = code.code();
        _this.nTotal = sum(_this.myCode.map(function(c) { return c.nSubTotal; }));
      });
    });

  };

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js" data-semver="1.4.7" data-require="angular.js@1.4.x"></script>
<div ng-app="plunker" ng-controller="MainCtrl as MainCtrl" ng-init="MainCtrl.init()">
  <div ng-repeat="rule in MainCtrl.myCode">

    Input_{{$index}}:
    <input ng-model="rule.inpValue" type="number" />

    Subtotal: {{rule.nSubTotal}}
    <br />

  </div>
  <br />

  <!-- the following should be a sum of all values above -->
  Total: {{MainCtrl.nTotal}}

  <br />
  <br />

</div>

于 2015-10-23T21:13:46.793 に答える
1

に対して常に評価される式を見ているため、あなた$watchは発砲していません。一連のアイテムの変更を監視する場合、いくつかのオプションがあります。undefined$scope

  1. $watchアイテムごとにセパレート。特に配列が大きい場合、あまり効率的ではありません。
  2. ウォッチ式の$watchGroup配列を受け入れる 。異なるオブジェクトの異なるプロパティなど、式が均一でない場合に便利です。
  3. A $watchCollection、単一のオブジェクトを浅く監視します。これがあなたの状況に最適だと思います。

また、 の最初の引数$watch*は、監視したい値を返す関数にすることができることに注意してください。これをまとめると、ウォッチャーは次のようになります

$scope.$watchCollection(function() {
  var aInputs = [];
  for (var i = 0, len = myCode.length; i < len; ++i) {
    aInputs.push(myCode[i].inpValue);
  }
  return aInputs;
}, function() {
  // one of the inpValues in myCode has changed
  // need to re-compute nTotal
});

また、eval()関数を使用するという JLRishe の提案を使用せず、それに従うことを強くお勧めします。文字列式を評価する必要がある場合は、Angular の$scope.$eval. これは、スコープと一連のローカル変数に対して式を評価します。例えば、

$scope.$eval("inpValue + 2", { inpValue: 3 }) === 5;

これが動作中のPlunkerです。概念実証として使用$evalしますが、可能であれば単純な関数を使用してください。

于 2015-10-23T21:34:16.910 に答える