【问题标题】:How to save Firebase objects $asArray() with angularFire, when the objects contain ng-repetate当对象包含 ng-repetate 时,如何使用 angularFire 保存 Firebase 对象 $asArray()
【发布时间】:2014-10-03 12:13:33
【问题描述】:

我最近从 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 $$hash 值。这在 angularfire 0.6.0 中有效。

在 angularfire 0.8.0 中,我仍然收到错误:

错误:Firebase.set 失败:第一个参数包含无效键 ($$hashKey) 在属性“durations.0”中。键必须是非空字符串 并且不能包含“.”、“#”、“$”、“/”、“[”或“]

在处理对象时,angularfire 是如何解决这个问题的,这些对象内部有数组?持续时间不会是我在帐户中拥有的唯一数组。那么有没有更专业的解决方案,还是我必须在通过 angularfire 保存到 firebase 之前 angular.copy 每个数组对象?

提前感谢您的任何提示。

更新(11. 8 月 14 日) 在做了更多研究之后,问题不在于使用 angular.copy() 不再起作用。实际上确实如此。但是使用 angularfire 方法 $save() (https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebaseobject-save) 更新/修改现有数据集非常不方便,因为在执行 angular.copy() 之后我似乎找不到 $save() 项目的正确方法.

更新 2(14 年 8 月 12 日) 我暂时找到了一种解决方法,但实际上我首先要避免的是一种解决方法:

// 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 解决方案。我可能没有正确添加行 - 或者我错过了什么?

【问题讨论】:

  • 您在 angularfire 0.8.0 中使用哪个版本的 angularjs?
  • 我在您的数据或设置或保存此列表的任何代码中看不到任何 $$hashKey。那是从哪里来的?如果问题集不完整,将很难提出修复建议。
  • 我使用的是 Angular 1.2.21。 $$hashKey 由 ng-repeat 以角度生成。实际上,在使用 $add() (firebase.com/docs/web/libraries/angular/…) angular.copy() 方法创建帐户期间。但是在更新数据时使用 $save() 时我不能使用 angular.copy() (firebase.com/docs/web/libraries/angular/…)
  • 您的代码仍然不完整。我们在复制什么(为什么?)。 $asObject() 在哪里使用?尝试创建一小段代码来重现您的问题。这将产生更智能的答案和更快的修复。
  • @Rias,这种结构仍然没有任何意义。如果您想要一组持续时间,请获取这些。不要将父级(帐户/)作为对象获取,然后尝试将其子级用作集合。嵌入式数组不起作用,因为 Angular 将无效属性附加到它。我会研究一些关于未来版本的想法。但是,AngularFire 是一个绑定库——它绑定对象和集合——而不是 Firebase 数据树的本地副本。直接获取收藏就行了。

标签: angularjs multidimensional-array angularjs-ng-repeat firebase angularfire


【解决方案1】:

当然,像@Kato 提到的在firebase 中解决它的最佳方法是实时绑定到数组中的数据到视图中,您应该通过$asArray 实例使用额外的firebase 同步对象。

就像在这个解决方案中:http://jsfiddle.net/RaVbaker/sb00kor8/1/ 但是你会失去使用像Save to Firebase 这样的按钮“按需”保存数据的可能性。在 firebase 数组对象发生更改后,它们将立即保存。但它也会为您提供跨页面数据的灵活性和同步性。

但在您的情况下,其他更简单的方法是在 ng-repeat 指令中更改角度跟踪对象唯一性的方式。可以通过在ng-repeat 语句末尾设置track by $index 来完成。

ng-repeat="duration in account.durations"改成这个:

 ng-repeat="duration in account.durations track by $index"

您的 jsfiddle 已使用此解决方案更新:http://jsfiddle.net/RaVbaker/sb00kor8/2/

关于 ngRepeat 的 track by 的更多信息,您显然可以找到 in official documentation

希望我能帮上忙。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    相关资源
    最近更新 更多