我最近从angularfire 0.6切换到0.8.0。我在保存包含数组本身的列表项时遇到问题。
我的对象帐户如下所示:
{
"-JQruasomekeys0nrXxH" : {
"created" : "2014-03-23T22:00:10.176Z",
"durations" : [ {
"$$hashKey": "00L", // this is generated by ng-repeat on arrays
"end" : "2014-07-15T22:00:00.000Z",
"start" : "2014-07-09T22:00:00.000Z"
} ],
"email" : "some@mail.net",
}
}
持续时间是一个包含开始和结束的时间段数组,类似于HTML中两个输入字段的ng-repeat。
<tr ng-repeat="duration in account.durations">
<td>
<input ng-model="duration.start" datepicker>
</td>
<td>
<input ng-model="duration.end" datepicker>
</td>
</tr>
在将帐户保存到firebase之前,我在Controller中执行angular.copy($ scope.account),以摆脱angular $$哈希值。这适用于angularfire 0.6.0。
在angularfire 0.8.0中,我仍然收到错误:
错误:Firebase.set失败:第一个参数包含无效密钥 ($$ hashKey)在属性'durations.0'中。键必须是非空字符串 并且不能包含“。”,“#”,“$”,“/”,“[”或“]
当处理具有数组的对象时,angularfire是如何解决的?持续时间不是我在帐户中唯一的数组。那么是否有一个更专业的解决方案,或者我必须在每个数组对象上进行angular.copy,然后通过angularfire保存到firebase?
提前感谢任何提示。
更新(11月14日) 在做了一些研究之后,问题不在于使用angular.copy()不再起作用。实际上确实如此。但是使用angularfire方法更新/修改现有数据集非常不方便$ save()(https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebaseobject-save)因为在做angular.copy之后我似乎无法找到$ save()项目的正确方法()。
更新2(8月12日14日) 我暂时找到了一种解决方法,但实际上解决方法是我想要首先避免的:
// loop for every duration, that should clean the object from "$$hashKey" attributes
angular.forEach($scope.account.durations, function (value, index) {
var cleanValue = {};
// checks, if the date is a JSON string already
if (typeof value.start === 'string') {
cleanValue.start = value.start;
} else {
cleanValue.start = value.start.toJSON();
}
// checks, if the date is a JSON string already
if (typeof value.end === 'string') {
cleanValue.end = value.end;
} else {
cleanValue.end = value.end.toJSON();
}
// overwrite the array object at index to get loose of $$hashKey
$scope.account.durations[index] = cleanValue;
});
我认为这种解决方法在Firebase中利用了基于文档的原则,因为在通过AngularFire存储之前我必须知道对象的确切属性。
更新3(13. AUg 14) 我添加了一个jsfiddle来显示问题:jsfiddle.net/1fem6byt
如果向数组添加行,然后尝试将对象保存到firebase,则会在控制台中显示$$ hashKey错误(上面给出)。有办法解决这个问题,但如果可能的话,我正在寻找一个更简单,更清晰的angularfire解决方案。我可能没有正确添加行 - 或者我错过了什么?
答案 0 :(得分:1)
当然在firebase中解决它的最好方法就像提到的@Kato并且实时绑定到数组中的数据到视图中你应该通过$ asArray实例使用额外的firebase同步对象。
就像在这个解决方案中一样:http://jsfiddle.net/RaVbaker/sb00kor8/1/但是你会失去使用像Save to Firebase
这样的按钮“按需”保存数据的可能性。在firebase数组对象发生更改后,它们将立即保存。但它也会为您提供跨页面数据的灵活性和同步性。
但在您的情况下,其他更容易的是在 ng-repeat 指令中更改角度跟踪对象唯一性的方式。可以通过在track by $index
语句末尾设置ng-repeat
来完成此操作。
将ng-repeat="duration in account.durations"
更改为:
ng-repeat="duration in account.durations track by $index"
您的jsfiddle已使用此解决方案进行了更新:http://jsfiddle.net/RaVbaker/sb00kor8/2/
有关ng track by
更多关于ngRepeat的信息,您可以找到in official documentation。
希望我帮助过。