我尝试创建一个列表组件,该组件绑定到定义列元数据和行值的列表。例如:
var list = {
cols: [
{ name: "date", display: "Date", type: "date" },
{ name: "revenue", display: "Revenue", type: "dollars" }
],
data: [
{ date: "1/2/34", revenue: 10 },
{ date: "2/3/45", revenue: 20 },
....
]
}
这很简单,使用ng-repeat迭代行然后另一个ng-repeat迭代列,看起来像这样:
<tr ng-repeat="row in list.data">
<td ng-repeat="col in list.cols">
{{ row[col.name] }}
</td>
</tr>
我也希望这个列表可以编辑并支持多种类型的控件,所以我的表看起来更像是这样:
<tr ng-repeat="row in list.data">
<td ng-repeat="col in list.cols">
<span ng-if="editing == $parent.$index" ng-switch on="col.type">
<input ng-switch-default ng-model="row[col.name]">
<span ng-switch-when="pselect" pselect="col.options" ng-model="row[col.name]"></span>
</span>
<span ng-if="editing != $parent.$index" ng-switch on="col.type" ng-click="editRow($parent.$parent.$index)">
<span ng-switch-when="dollars">{{row[col.name] | currency}}</span>
<span ng-switch-default>{{row[col.name]}}</span>
</span>
</td>
</tr>
此示例中的pselect是我的自定义下拉指令。我的目标是能够在该指令中使用ng-model将其值绑定到list指令作用域中的对象(绑定到我的外部作用域)。当尝试在pselect的隔离范围和外部范围之间同步模型值时,我的问题出现了。由于隔离范围在pselect和ng-model指令之间共享,因此ng-model指令与包含范围分离。我一直在使用此变通方法(https://stackoverflow.com/a/15272359/1655272)来同步范围之间的更改:
scope.$watch("model", function() {
scope.$eval(attrs.ngModel + " = model");
});
scope.$watch(attrs.ngModel, function(val) {
scope.model = val;
});
但是使用这种方法,我在列表组件的ng-repeat中遇到了一个问题。请注意,在pselect控件ng-model="row[col.name]"
上。尝试创建名为row[col.name]
的本地范围变量时,前一个方法失败,因为未定义行。如果我创建了一个变量scope.row = {}
,则会避免此错误,但这只是一个黑客攻击。
之前有没有人遇到过类似的问题?我觉得我忽略了一个更明显的解决方案,但我似乎无法处理指令和范围之间的相互作用。