2016-02-04 75 views
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'] +"} 
 
]

+0

你可以修改你的服務。 ? –

+0

我可以,如果我必須。你有什麼建議? – Chen

回答

0

哦,我的上帝!我做的!看看:)

當然,這個解決方案並不完美。它取決於控制器中使用的變量名稱。但它的作品!

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;}) 
+0

嗨斯捷潘,你的第二個解決方案是輝煌的,我沒有弄清楚。這太棒了。 – Chen

0

如果你需要計算基礎上,expresion屬性的值,你應該先tokanize領域指標在表達自己的數學運算符在一起。這個過程的複雜性因您在表達式中允許的數學印象類型而異。

如:

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

那麼你應該通過比較它們對陣列計算彙總值這些令牌。

-

一種替代方式,這如果表達式是來自用戶的我不推薦,是創建具有它裏面的所有這些變量FNAME私人範圍對象,並使用eval功能針對上下文通過抽象。

你可以在this的答案得到解決這個問題的方法。

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'] +"} 
    ] 

結合工作,你可以把一切都放在這是一個函數重新評估當一個屬性的變化。

退房它HERE