首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态添加$watch

动态添加$watch
EN

Stack Overflow用户
提问于 2015-10-24 04:44:43
回答 2查看 3.6K关注 0票数 1

我有一个JSON数据集,其中每一行都包括一个输入值、一小段用于计算的JavaScript代码以及一个小计数值(它是eval()执行计算后输入值的结果)。dataset将包含一行或多行。每个输入都将以HTML格式重复到页面上,并且小计的总和将与每个单独的小计值一起显示给用户。

我尝试使用$watch并为中继器中的每一行添加一个,但似乎无法在用户更改输入值时触发它们。

我已经创建了我的第一个Sample_Plunker 来演示我试图实现的目标,但没有成功。

不确定我是否也应该在这里张贴代码,但任何帮助都将非常感谢。

基本上是我的HTML:

代码语言:javascript
复制
<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:

代码语言:javascript
复制
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()
});
EN

回答 2

Stack Overflow用户

发布于 2015-10-24 05:13:47

您的代码有很多错误,但基本上为了回答您的问题,您可以对数组中的每一项应用监视,方法是遍历数组并为每个元素调用一次$scope.$watch

我还强烈建议您使用实际的函数而不是eval()来计算表达式。

代码语言:javascript
复制
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; }));
      });
    });

  };

});
代码语言:javascript
复制
<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>

票数 4
EN

Stack Overflow用户

发布于 2015-10-24 05:34:17

您的$watch未触发,因为您正在观察一个表达式,该表达式的计算结果始终为$scopeundefined。在查看一组项目的更改时,您有以下几个选项:

  1. 每个项目都有一个单独的$watch。效率不是很高,特别是在数组很大的情况下。
  2. 接受监视表达式数组的$watchGroup。当表达式不一致时非常有用,例如,不同对象的不同属性。
  3. 一个$watchCollection,它浅观察单个对象。我认为这最适合你的情况。

还要注意,$watch*的第一个参数可以是返回您想要监视的值的函数。把这些放在一起,你的观察者可能看起来像

代码语言:javascript
复制
$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安全地执行此操作。这将根据作用域和一组局部变量计算表达式。例如,

代码语言:javascript
复制
$scope.$eval("inpValue + 2", { inpValue: 3 }) === 5;

这是一个有效的Plunker。它使用$eval作为概念证明,但同样,如果可以的话,请使用普通函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33311105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档