给定一个对象数组(例如,表示选择项目)和输入,如何绑定输入值以便它表示所有对象的给定属性?
输入应以以下方式显示状态:
我有一个函数聚合在范围上公开的给定属性的值:
// Return value (if all values are equal) or undefined (if not)
scope.getSelection('property')
我还有一个在所有对象上设置值的函数:
scope.setSelection('property', value)
我找不到组合ng-value,ng-model和ng-change,它允许我自动从.getSelection()获取并设置为.setSelection(),所以我假设我必须写一个新的指令。
解决这个问题的惯用方法是什么?
答案 0 :(得分:2)
为了将来参考,让我写一个完整的答案:
在相当现代的浏览器中实现此目的的一种方法是使用属性getter / setters(spec)。一个示例,概念验证实现将是:
假设$scope
包含以下集合:
$scope.items = [
{id: 1, prop: "a"},
{id: 2, prop: "a"},
{id: 3, prop: "a"}
];
我们想要操纵item.prop
属性的聚合。我们将另一个对象定义为:
$scope.form = {
get aggregate() {
var res, i;
for( i=0; i < $scope.items.length; i++ ) {
if( typeof(res) === "undefined" ) {
res = $scope.items[i].prop;
}
else if( $scope.items[i].prop !== res ) {
return "(multiple)";
}
}
return res;
},
set aggregate(val) {
var i;
for( i=0; i < $scope.items.length; i++ ) {
$scope.items[i].prop = val;
}
}
};
form.aggregate
属性现在有一个getter和setter。这些函数通过迭代$scope.items
来处理它们的值。 getter比较值并返回公共值,如果全部相同则返回"(multiple)"
(如果至少有一个不同)。 setter只是将给定值设置为所有属性。
小提琴:http://jsfiddle.net/52HE6/
改进的(IMO)版本,使用占位符代替文字"(multiple)"
:http://jsfiddle.net/52HE6/1/
这种模式可能是通用的/参数化的(即没有固定名称prop
),例如as(警告:UNTESTED):
function aggregatorFactory($scope, collectionName, propName) {
return {
get aggregate() {
var res, i;
for( i=0; i < $scope[collectionName].length; i++ ) {
if( typeof(res) === "undefined" ) {
res = $scope[collectionName][i][propName];
}
else if( $scope[collectionName][i][propName] !== res ) {
return "(multiple)";
}
}
return res;
},
set aggregate(val) {
var i;
for( i=0; i < $scope[collectionName].length; i++ ) {
$scope[collectionName][i][propName] = val;
}
}
};
}