1

我需要根据从服务返回的表达式动态显示小计。请参阅下面的示例项目结构。属性值绑定到文本输入。如果任何输入值发生变化,则根据标签中的表达式更新小计。最好的方法是什么?

注意:字段名/值对的数量可能会有所不同。

$scope.item = [
  {fieldName: "fname1", value: 2},
  {fieldName: "fname2", value: 5},
  {fieldName: "fname3", value: 4},
  {fieldName: "fname4", value: 6},
  {fieldName: "fname5", value: 3},
  {fieldName: "subTotal1", expression: "['fname1'] + ['fname2'] +['fname3'] +['fname4'] +['fname5'] +"}
]

4

3 回答 3

1

我的天啊!我做的!看 :)

当然,这个解决方案并不完美。它取决于控制器中使用的变量名称。但它有效!

jsfiddle上的实时示例。

<form name="ExampleForm" id="ExampleForm">
  <div ng-repeat="item in items">
    <div ng-if="item.fieldName!='subTotal1'">
      <input ng-model="item.value">
      <my-ng-model n-name="{{item.fieldName}}" n-value="item.value" obj="obj"></my-ng-model>
    </div>
    <div ng-if="item.fieldName=='subTotal1'">
      {{item.expression }}={{$eval(item.expression)}}
    </div>
  </div>
  {{obj|json}}
</form>

和js控制器:

.controller('ExampleController', function($scope, $parse) {
$scope.obj = {};
$scope.items = [{
  fieldName: "fname1",
  value: 2
}, {
  fieldName: "fname2",
  value: 5
}, {
  fieldName: "fname3",
  value: 4
}, {
  fieldName: "fname4",
  value: 6
}, {
  fieldName: "fname5",
  value: 3
}, {
  fieldName: "subTotal1",
  expression: "obj.fname1 + obj.fname2 +obj.fname3 +obj.fname4 +obj.fname5"
}];})

和 js 指令:

.directive('myNgModel', function() {
var root = {
  restrict: "E",
  replace: true,
  scope: {
    nName: "@",
    nValue: "=",
    obj: "="
  },
  template: '<div></div>',
  link: function(scope) {
    scope.obj[scope.nName] = scope.nValue*1;
    scope.$watch('nValue', function(value) {
      scope.obj[scope.nName] = value*1;
    });
  }
}
return root; })

更新

现在它可以在不引用局部变量的情况下工作!

jsfiddle上的实时示例。

<form name="ExampleForm" id="ExampleForm">
  <div ng-repeat="item in items">
    <div ng-if="item.fieldName!='subTotal1'">
      <input ng-model="item.value">
      <my-ng-model n-name="{{item.fieldName}}" n-value="item.value" obj="obj"></my-ng-model>
    </div>
  </div>
  <div ng-repeat="eval in evals">
    {{eval.expression }}={{$eval(eval.expression,obj)}}
  </div>
</form>

控制器

.controller('ExampleController', function($scope, $parse) {
$scope.obj = {};
$scope.items = [{
  fieldName: "fname1",
  value: 2
}, {
  fieldName: "fname2",
  value: 5
}, {
  fieldName: "fname3",
  value: 4
}, {
  fieldName: "fname4",
  value: 6
}, {
  fieldName: "fname5",
  value: 3
}, {
  fieldName: "subTotal1",
  expression: "fname1 + fname2 +fname3 +fname4 +fname5"
}];
$scope.evals = [];
angular.forEach($scope.items, function(item) {
  if (item.expression) {
    $scope.evals.push({
      expression: item.expression
    });
  }
});})

和指令

.directive('myNgModel', function() {
var root = {
  restrict: "E",
  replace: true,
  scope: {
    nName: "@",
    nValue: "=",
    obj: "="
  },
  link: function(scope) {
    scope.obj[scope.nName] = scope.nValue * 1;
    scope.$watch('nValue', function(value) {
      scope.obj[scope.nName] = value * 1;
    });
  }
}
return root;})
于 2016-02-04T13:18:56.007 回答
0

如果您需要根据expresion属性计算值,您应该首先将字段指示符连同它们的数学运算符一起在表达式中进行tokanize。此过程的复杂性因表达式中允许的数学印象类型而异。

例如:

[fName1] + [fName2] - [fName3]    // is a simple expression
[fName1] * ([fName2] + [fName3])  // is complex than that

然后,您应该通过将它们与数组进行比较来计算这些标记的聚合值。

--

如果表达式来自用户,我不推荐的另一种方法是创建一个私有范围对象,其中包含所有这些 fName 变量,并eval通过抽象对该上下文使用函数。

您可以在此答案中了解此方法。

于 2016-02-04T12:27:59.567 回答
0

我写了一个小提琴来解决你的问题。它可以提高,但我现在没有时间。你可以自己做。

它基于您发布的模型:

  $scope.item = [
    {fieldName: "fname1", value: 2},
    {fieldName: "fname2", value: 5},
    {fieldName: "fname3", value: 4},
    {fieldName: "fname4", value: 6},
    {fieldName: "fname5", value: 3},
    {fieldName: "subTotal1", expression: "['fname1'] + ['fname2'] +['fname3'] +['fname4'] +['fname5'] +"}
  ]

为了使绑定起作用,您可以将所有内容放在一个函数中,该函数会在属性更改时重新评估。

在这里查看

于 2016-02-04T12:33:28.443 回答