我的对象帐户看起来像这样:
{ "-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中,我仍然收到错误:
Error: Firebase.set Failed: First argument contains an invalid key
($$hashKey) in property ‘durations.0’. Keys must be non-empty strings
and can’t contain “.”,“#”,“$”,“/”,“[“,or “]
当处理具有阵列的对象时,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解决方案.我可能没有正确添加行 – 或者我错过了什么?
解决方法
就像在这个解决方案中一样:http://jsfiddle.net/RaVbaker/sb00kor8/1/但是你可以通过Save to Firebase这样的按钮“按需”保存数据.在firebase数组对象发生更改后,它们将立即保存.但它也会为您提供跨页面数据的灵活性和同步性.
但在你的情况下,其他更容易的是改变角度跟踪ng-repeat指令中对象唯一性的方式.可以通过在ng-repeat语句的末尾按$index设置跟踪来完成.
将ng-repeat =“account.durations中的持续时间”更改为:
ng-repeat="duration in account.durations track by $index"
您的jsfiddle已使用此解决方案更新:http://jsfiddle.net/RaVbaker/sb00kor8/2/
有关track by for ngRepeat的更多信息,你会发现很明显in official documentation.
希望我帮忙.