Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit d5f7ad9

Browse files
committed
Merge pull request #546 from jamestalmage/bindto-performance-enhancement
Bindto performance enhancement and fixes.
2 parents 3a6cae3 + 49850fe commit d5f7ad9

File tree

2 files changed

+46
-28
lines changed

2 files changed

+46
-28
lines changed

src/FirebaseObject.js

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -318,56 +318,47 @@
318318
self.scope = scope;
319319
self.varName = varName;
320320

321-
function equals(rec) {
322-
var parsed = getScope();
323-
var newData = $firebaseUtils.scopeData(rec);
324-
return angular.equals(parsed, newData) &&
325-
parsed.$priority === rec.$priority &&
326-
parsed.$value === rec.$value;
327-
}
328-
329-
function getScope() {
330-
return $firebaseUtils.scopeData(parsed(scope));
321+
function equals(scopeValue) {
322+
return angular.equals(scopeValue, rec) &&
323+
scopeValue.$priority === rec.$priority &&
324+
scopeValue.$value === rec.$value;
331325
}
332326

333327
function setScope(rec) {
334328
parsed.assign(scope, $firebaseUtils.scopeData(rec));
335329
}
336330

337-
var send = $firebaseUtils.debounce(function() {
338-
rec.$$scopeUpdated(getScope())
331+
var send = $firebaseUtils.debounce(function(val) {
332+
rec.$$scopeUpdated($firebaseUtils.scopeData(val))
339333
['finally'](function() { sending = false; });
340334
}, 50, 500);
341335

342-
var scopeUpdated = function() {
343-
if( !equals(rec) ) {
336+
var scopeUpdated = function(newVal) {
337+
newVal = newVal[0];
338+
if( !equals(newVal) ) {
344339
sending = true;
345-
send();
340+
send(newVal);
346341
}
347342
};
348343

349344
var recUpdated = function() {
350-
if( !sending && !equals(rec) ) {
345+
if( !sending && !equals(parsed(scope)) ) {
351346
setScope(rec);
352347
}
353348
};
354349

355350
// $watch will not check any vars prefixed with $, so we
356351
// manually check $priority and $value using this method
357-
function checkMetaVars() {
358-
var dat = parsed(scope);
359-
if( dat.$value !== rec.$value || dat.$priority !== rec.$priority ) {
360-
scopeUpdated();
361-
}
352+
function watchExp(){
353+
var obj = parsed(scope);
354+
return [obj, obj.$priority, obj.$value];
362355
}
363356

364-
self.subs.push(scope.$watch(checkMetaVars));
365-
366357
setScope(rec);
367358
self.subs.push(scope.$on('$destroy', self.unbind.bind(self)));
368359

369360
// monitor scope for any changes
370-
self.subs.push(scope.$watch(varName, scopeUpdated, true));
361+
self.subs.push(scope.$watch(watchExp, scopeUpdated, true));
371362

372363
// monitor the object for changes
373364
self.subs.push(rec.$watch(recUpdated));

tests/unit/FirebaseObject.spec.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,7 @@ describe('$FirebaseObject', function() {
331331
$scope.test.$priority = 999;
332332
});
333333
$interval.flush(500);
334-
$timeout.flush(); // for $interval
335-
$timeout.flush(); // for $watch
334+
$timeout.flush();
336335
expect(spy).toHaveBeenCalledWith(jasmine.objectContaining({'.priority': 999}));
337336
});
338337

@@ -348,11 +347,39 @@ describe('$FirebaseObject', function() {
348347
$scope.test.$value = 'bar';
349348
});
350349
$interval.flush(500);
351-
$timeout.flush(); // for $interval
352-
$timeout.flush(); // for $watch
350+
$timeout.flush();
353351
expect(spy).toHaveBeenCalledWith(jasmine.objectContaining({'.value': 'bar'}));
354352
});
355353

354+
it('should only call $$scopeUpdated once if both metaVars and properties change in the same $digest',function(){
355+
var $scope = $rootScope.$new();
356+
var fb = new MockFirebase();
357+
fb.autoFlush(true);
358+
fb.setWithPriority({text:'hello'},3);
359+
var $fb = new $firebase(fb);
360+
var obj = $fb.$asObject();
361+
flushAll();
362+
flushAll();
363+
obj.$bindTo($scope, 'test');
364+
$scope.$apply();
365+
expect($scope.test).toEqual({text:'hello', $id: obj.$id, $priority: 3});
366+
var callCount = 0;
367+
var old$scopeUpdated = obj.$$scopeUpdated;
368+
obj.$$scopeUpdated = function(){
369+
callCount++;
370+
return old$scopeUpdated.apply(this,arguments);
371+
};
372+
$scope.$apply(function(){
373+
$scope.test.text='goodbye';
374+
$scope.test.$priority=4;
375+
});
376+
flushAll();
377+
flushAll();
378+
flushAll();
379+
flushAll();
380+
expect(callCount).toEqual(1);
381+
});
382+
356383
it('should throw error if double bound', function() {
357384
var $scope = $rootScope.$new();
358385
var aSpy = jasmine.createSpy('firstBind');

0 commit comments

Comments
 (0)