如何在AngularJs模型中声明计算字段?如果我这样做:
$scope.model = {
id: null,
calculatedField: function() {
return 1+2;
}
};
然后将整个对象发送到Web服务器,如下所示:
$http.post(url, $scope.model)...
它总是为calculatedField
字段值发送null。在将对象序列化为Json时,它似乎需要属性,而不是函数。
更新:我希望每次在Json中序列化模型时自动调用computedField()
答案 0 :(得分:5)
如果calculatedField
的行为与某个值相同,那么只需将其设为getter:
$scope.model = {
id: null,
get calculatedField() {
return 1+2;
}
};
除了不能为其赋值外,您可以像使用常规值属性一样使用它。当然,它也可以正确序列化。
var x = $scope.model.calculatedField; // x = 3
$scope.model.calculatedField = 4; //doesn't change calculatedField
JSON.stringify($scope.model); // "{"id":null,"calculatedField":3}"
Getters是常规的JavaScript btw。
答案 1 :(得分:1)
您已经发现JavaScript和Angular并不真正提供开箱即用的情况。您将不得不在应用程序中以最佳方式做出决定。
控制对象序列化为JSON的最简单方法是添加toJSON()
method。这与toString()
方法类似,但不是返回字符串表示,而是返回要转换为JSON的对象表示。
以下是模型的示例,它将从模型复制到返回对象。但是,对于每个函数,它将输出调用该函数的结果:
$scope.model = {
id: null,
calculatedField: function() {
return 1+2;
},
/**
* Return an object that represents this model
* instance and will be converted to JSON.
*/
toJSON: function(){
var o = {};
angular.forEach(this, function(value, key){
if (angular.isFunction(value)){
o[key] = value();
} else {
o[key] = value;
}
}, this);
return o;
}
};
JSON序列化结果:
console.log(angular.toJson($scope.model));
/*
{
"id": null,
"calculatedField": 3
}
*/
请注意,当对象序列化为JSON时,会自动调用toJSON()
方法。这意味着您可以在将其发布到服务器之前忘记调用它
另一件好事是,如果您使用toJSON()
方法嵌套对象,它们也会在对象图中一直被调用。
这应该为您提供了一个制定序列化模型的最佳方法的起点。
从这里你可以调整上面的toJSON()
示例 - 即是否应该从JSON输出中排除某些方法或属性。
以下是如何过滤掉特定属性/功能的示例:
$scope.model = {
id: null,
calculatedField: function() {
return 1+2;
},
// Example function we don't want serialised at all.
myNonCalculatedField: function(param1, param2){
return param1 + param2;
},
/**
* Return an object that represents this model
* instance and will be converted to JSON.
*/
'@exclude': {
'@exclude': false,
'myNonCalculatedField': false
},
toJSON: function(){
var o = {};
var excludeMap = this['@exclude'];
angular.forEach(this, function(value, key){
// Skip any property that we've marked as excluded.
if (excludeMap[key] === false){
return;
}
// Copy everything else to the return object.
if (angular.isFunction(value)){
o[key] = value();
} else {
o[key] = value;
}
}, this);
return o;
}
};
答案 2 :(得分:0)
使用常规函数而不是匿名函数。
实施例。
var field = function(){
return 1+2;
}
$scope.model = {
id: null,
calculatedField: field()
};
答案 3 :(得分:0)
var myFun = function() {
return 1+2;
};
如果您想发送返回值:
$scope.model = {
id: null,
calculatedField: myFun()
};
如果您想发送函数的定义:
$scope.model = {
id: null,
calculatedField: myFun.toString()// convert the function to string.
};
重新计算:
$scope.calculatedField = myFun();
$http.post(url, $scope.model)...
在JS中,如果你想要自动更新之类的东西,可以使用对象首选项:
var var_1 = {a: 123};
var var_2 = var_1;
var_1.a = 456;//change value 'a' in var_1.
console.log(var_2.a)//the value 'a' in var_2 is 456 also.
更新:如果您希望每次更改模型时自动调用computedField(),您可以尝试在angularjs中使用$ watch:
$scope.$watch('modelToWatch', function(newVal, oldVal) {
calculatedField();
});