【发布时间】:2015-02-13 13:09:04
【问题描述】:
我正在构建一个时间线系统,它基本上是由许多不同的指令构成的。
在抽象中,每个项目看起来像这样:
<project id='id'>
<h3 ng-bind='project.name'></h3>
<timeline items='project.timelines[0]'>
<timeline-item item='item' ng-repeat='item in timeline'>
<comments items='item.comments'>
<comment item='comment' ng-repeat='comment in comments'>
<user id='comment.user'></user>
<p ng-bind='comment.body'></p>
</comment>
</comments>
</timeline-item>
</timeline>
</project>
在顶层,我通过获取对项目的原始 firebase 引用来为项目创建对象,然后将其包装在 $firebase 包装器中。最后,我使用$asObject() 为模型准备了一份副本。
这种技术非常适合<project> 指令,因为我可以访问所有顶级属性以及.$save() 方法。
但是,当我将此对象的子级传递给子级指令时,我将无法调用.$save()。这意味着模型会在视图中完美更新,但不会保存在 Firebase 中。
一般来说,如何从现有的$FirebaseObject 中提取$FirebaseObject 或$FirebaseArray 以传递给指令?
我知道我可以获取原始参考来实现这一点,但实际上这看起来像:
...
// timeline-item.js
scope: {
item: '='
},
link: function(scope) {
scope.item; // is a $FirebaseObject
scope.comments scope.item.$ref().child('comments');
},
template:
"<comments items='comments'></comments>"
// comments.js
scope: {
items: '='
},
link: function(scope) {
scope.items; // is a Firebase reference
scope.items = $firebase(scope.items).$asArray();
}
也许这个问题可以用$bindTo解决?但我也不知道这将如何跨多个指令工作。
【问题讨论】:
-
您可以从
$firebase对象中获取$ref,并在此基础上构造正确的新$firebase对象。但是,如果您显示您的控制器/服务代码而不是描述它,会更容易提供帮助。 -
有许多不同类型的时间线项目,并且一起描述完整时间线系统的服务代码要复杂得多,当目标是这个抽象时,我可以证明提出一个 SO 问题是合理的在自然界。我知道我可以取回 $ref,但是您必须通过调用
.child()来重建您的路径,然后将该子引用向下传递,只需要用$firebase重新包装它并获取新对象。感觉很乱在以前版本的 AngularFire 中,我会使用$child调用来完成此操作,但 0.8x API 已将其删除。 -
如果你不能simplify your code to a simple problem statement,那么一个简单的答案也是不可能的。 $child 被删除是因为它是多余的,而且在人们使用它的所有情况下,他们都错误地利用它来将特征侵入到他们的对象中或操纵数据。我们以 $extend 的形式为这些提供了新工具。您的数据结构过于复杂。 Avoid building nests 尽可能。
-
关于为什么应该将其简化为可定义的问题集的另一个论点,请参阅the XY problem,您已经陷入了这里。请注意,我们在 paragraph 2 of the guide 中专门解决了这样的嵌套结构:“[AngularFire] 也不适合在集合内同步深度嵌套的集合。但在分布式系统中通常应该避免深度嵌套的集合。”
-
等一下,我知道这里有很多细节,但我认为加粗的文本“如何从现有的 $FirebaseObject 中提取 $FirebaseObject 或 $FirebaseArray 以传递给指令?”既简单又明确定义为一个问题?您推荐了关于扁平化数据的指南这一事实证明我没有陷入 XY,因为您已经能够很好地理解问题并提出解决方案。不过,这是一个有用的指南,所以谢谢。
标签: javascript angularjs firebase angularfire