我目前的解决方案是使用这样的装饰器函数:
HTML:
<tr ng-repeat="(id, o) in todos" ng-init="t = decorate(id, o)">
<td>{{ t.name }}</td>
<td>{{ t.extra.data }}</td>
<td><a href="" ng-click="t.remove()">remove</a></td>
</tr>
JS:
...
$scope.todos = ... // sets as a firebase 3-ways binding collection
function Todo(id) {
this.id = id;
}
// remove the todo on firebase
Todo.prototype.remove = function() {
delete $scope.todos[this.id];
};
// decorate the object fetched by firebase
$scope.decorate = function(id, o) {
var t = _(new Todo(id)).extends(o);
// adds some extra data by fetching it from another firebase ref
someOtherFirebaseRef.once('value', function(snap) {
t.extra = snap.val();
});
return t;
};
...
答案 0 :(得分:0)
上述方法的问题在于,只要原始o
对象发生更改,它就不会更新。因此,$ scope.decorate返回的t
更像是静态快照,而不是Firebase和Angular之间的实时绑定。
一种方法是编写自己的服务。为了简化这个过程,使用双向数据绑定(例如$scope.todos = $firebase(ref)
)vs 3-way(例如$ firebase(ref)。$ bind($ scope,'todos')`),这将使整个过程适应这一点要简单得多。
示例:
app.factory('DecoratedObject', function($timeout) {
return function(ref1, ref2) {
var self = this;
this.data = {};
this.getData = function() {
return data;
};
this.save = function(fieldsForRef1, fieldsForRef2) {
ref1.set( _.pick(data||{}, fieldsForRef1);
ref2.set( _.pick(data||{}, fieldsForRef2);
};
this.dispose = function() {
ref1.off('value', dataUpdated);
ref2.off('value', dataUpdated);
};
function dataUpdated(snap) {
// $timeout forces Angular to run $apply and update the DOM
$timeout(function() {
_.extend(self.data, snap.val());
});
}
};
});
// and to use it
var obj = new DecoratedObject(ref1, ref2);
$scope.todos = obj.getData();
更复杂的方法是使用像Firebase.util这样的连接库,并跳过额外的工作:
// create a joined ref between two paths, which behaves just like a single ref
var ref = Firebase.join( ref1, ref2 );
// use it to create your angularFire object
$scope.todos = $firebase( ref );