Angularjs 动态添加$watch

Angularjs 动态添加$watch,angularjs,angularjs-watch,Angularjs,Angularjs Watch,我有一个JSON数据集,每行包括一个输入值、一小段用于计算的JavaScript代码和一个小计值,小计值是eval()执行计算后输入值的结果。数据集将包含一行或多行。每个输入都将以HTML格式在页面上重复,小计的总和将与每个单独的小计值一起作为总值显示给用户 我尝试使用$watch,并为中继器中的每一行添加一个,但当用户更改输入值时,我似乎无法启动它们 我已经创建了我的第一个,以证明我试图实现的目标没有成功 不知道我是否也应该张贴在这里的代码或没有,但任何帮助将不胜感激 基本上我的HTML: &

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

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

我已经创建了我的第一个,以证明我试图实现的目标没有成功

不知道我是否也应该张贴在这里的代码或没有,但任何帮助将不胜感激

基本上我的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>

您的代码有很多错误,但基本上要回答您的问题,您可以通过在数组中循环并为每个元素调用一次
$scope.$watch
来对数组中的每个项应用一个watch

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

var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数($scope){
var_this=这个;
_this.nTotal=0;
//稍后将执行示例js代码tht
_this.myCode=[{
“code”:函数(){返回this.inpValue+2;},
“输入值”:0,
“nSubTotal”:0
}, {
“code”:函数(){返回this.inpValue*3;},
“输入值”:0,
“nSubTotal”:0
}, {
“code”:函数(){返回this.inpValue/5;},
“输入值”:0,
“nSubTotal”:0
}];
函数和(值){
reduce(函数(a,b){returna+b;},0);
}
this.init=函数(){
_this.myCode.forEach(函数(代码){
$scope.$watch(函数(){
返回code.inp值;
},函数(){
code.nSubTotal=code.code();
_this.nTotal=sum(_this.myCode.map(函数(c){return c.nSubTotal;}));
});
});
};
});

输入{{$index}}:
小计:{rule.nSubTotal}


总计:{MainCtrl.nTotal}


您的代码有很多错误,但基本上为了回答您的问题,您可以通过在数组中循环并为每个元素调用
$scope.$watch
一次,对数组中的每个项目应用一个watch

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

var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数($scope){
var_this=这个;
_this.nTotal=0;
//稍后将执行示例js代码tht
_this.myCode=[{
“code”:函数(){返回this.inpValue+2;},
“输入值”:0,
“nSubTotal”:0
}, {
“code”:函数(){返回this.inpValue*3;},
“输入值”:0,
“nSubTotal”:0
}, {
“code”:函数(){返回this.inpValue/5;},
“输入值”:0,
“nSubTotal”:0
}];
函数和(值){
reduce(函数(a,b){returna+b;},0);
}
this.init=函数(){
_this.myCode.forEach(函数(代码){
$scope.$watch(函数(){
返回code.inp值;
},函数(){
code.nSubTotal=code.code();
_this.nTotal=sum(_this.myCode.map(函数(c){return c.nSubTotal;}));
});
});
};
});

输入{{$index}}:
小计:{rule.nSubTotal}


总计:{MainCtrl.nTotal}


您的
$watch
未触发,因为您正在查看一个表达式,该表达式将始终根据
$scope
计算为
未定义。在查看一组项目的更改时,您有几个选项:

  • 每个项目都有一个单独的
    $watch
    。效率不是很高,尤其是阵列较大时
  • 接受监视表达式数组的
    $watchGroup
    。表达式不一致时非常有用,例如不同对象的不同属性
  • $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
    作为概念证明,但如果可以的话,再次使用普通函数。

    您的
    $watch
    未触发,因为您正在查看一个表达式,该表达式将始终根据
    $scope
    计算为
    未定义的
    。在查看一组项目的更改时,您有几个选项:

  • 每个项目都有一个单独的
    $watch
    。效率不是很高,尤其是阵列较大时
  • 接受监视表达式数组的
    $watchGroup
    。表达式不一致时非常有用,例如不同对象的不同属性
  • $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
    作为概念证明,但如果可以的话,请再次使用普通函数。

    您的手表没有启动,因为在
    $scope
    上没有对手表表达式求值的属性
    i
    。你能详细解释一下这个数据集吗?为什么需要这些JS代码片段?在我看来,它们甚至都是无效的
    \u this.myCode.inpValue
    将解析为未定义,因为
    \u this.myCode
    是一个数组。没有通配符
    [i]
    使您的wat
    $scope.$eval("inpValue + 2", { inpValue: 3 }) === 5;