@@ -73,6 +73,7 @@ angular.module("firebase").filter("orderByPriority", function() {
7373AngularFire = function ( $q , $parse , $timeout , ref ) {
7474 this . _q = $q ;
7575 this . _bound = false ;
76+ this . _loaded = false ;
7677 this . _parse = $parse ;
7778 this . _timeout = $timeout ;
7879
@@ -211,6 +212,27 @@ AngularFire.prototype = {
211212 var self = this ;
212213 var gotInitialValue = function ( snapshot ) {
213214 var value = snapshot . val ( ) ;
215+ if ( value === null ) {
216+ // NULLs are handled specially. If there's a 3-way data binding
217+ // on a local primitive, then update that, otherwise switch to object
218+ // binding using child events.
219+ if ( self . _bound ) {
220+ var local = self . _parseObject ( self . _parse ( self . _name ) ( self . _scope ) ) ;
221+ switch ( typeof local ) {
222+ // Primitive defaults.
223+ case "string" :
224+ case "undefined" :
225+ value = "" ;
226+ break ;
227+ case "number" :
228+ value = 0 ;
229+ break ;
230+ case "boolean" :
231+ value = false ;
232+ break ;
233+ }
234+ }
235+ }
214236
215237 switch ( typeof value ) {
216238 // For primitive values, simply update the object returned.
@@ -229,6 +251,7 @@ AngularFire.prototype = {
229251 }
230252
231253 // Call handlers for the "loaded" event.
254+ self . _loaded = true ;
232255 self . _broadcastEvent ( "loaded" , value ) ;
233256 } ;
234257
@@ -314,15 +337,18 @@ AngularFire.prototype = {
314337 var self = this ;
315338 self . _timeout ( function ( ) {
316339 // Primitive values are represented as a special object {$value: value}.
317- self . _object . $value = value ;
340+ // Only update if the remote value is different from the local value.
341+ if ( ! self . _object . $value || ! angular . equals ( self . _object . $value , value ) ) {
342+ self . _object . $value = value ;
343+ }
318344
319345 // Call change handlers.
320346 self . _broadcastEvent ( "change" ) ;
321347
322348 // If there's an implicit binding, simply update the local scope model.
323349 if ( self . _bound ) {
324- var local = self . _parse ( self . _name ) ( self . _scope ) ;
325- if ( ! angular . equals ( value , local ) ) {
350+ var local = self . _parseObject ( self . _parse ( self . _name ) ( self . _scope ) ) ;
351+ if ( ! angular . equals ( local , value ) ) {
326352 self . _parse ( self . _name ) . assign ( self . _scope , value ) ;
327353 }
328354 }
@@ -359,17 +385,15 @@ AngularFire.prototype = {
359385 var self = this ;
360386 var deferred = self . _q . defer ( ) ;
361387
362- // _updateModel will take care of updating the local model if _bound
363- // is set to true.
388+ // _updateModel or _updatePrimitive will take care of updating the local
389+ // model if _bound is set to true.
364390 self . _name = name ;
365391 self . _bound = true ;
366392 self . _scope = scope ;
367393
368- // If the model on $scope is not set yet, make it an object .
394+ // If the local model is an object, call an update to set local values .
369395 var local = self . _parse ( name ) ( scope ) ;
370- if ( local === undefined ) {
371- self . _parse ( name ) . assign ( scope , { } ) ;
372- } else {
396+ if ( local !== undefined && typeof local == "object" ) {
373397 self . _fRef . update ( self . _parseObject ( local ) ) ;
374398 }
375399
@@ -378,10 +402,19 @@ AngularFire.prototype = {
378402 var unbind = scope . $watch ( name , function ( ) {
379403 // If the new local value matches the current remote value, we don't
380404 // trigger a remote update.
381- local = self . _parseObject ( self . _parse ( name ) ( scope ) ) ;
382- if ( angular . equals ( local , self . _object ) ) {
405+ var local = self . _parseObject ( self . _parse ( name ) ( scope ) ) ;
406+ if ( self . _object . $value && angular . equals ( local , self . _object . $value ) ) {
407+ return ;
408+ } else if ( angular . equals ( local , self . _object ) ) {
383409 return ;
384410 }
411+
412+ // If the local model is undefined or the remote data hasn't been
413+ // loaded yet, don't update.
414+ if ( local === undefined || ! self . _loaded ) {
415+ return ;
416+ }
417+
385418 // Use update if limits are in effect, set if not.
386419 if ( self . _fRef . set ) {
387420 self . _fRef . set ( local ) ;
@@ -403,6 +436,7 @@ AngularFire.prototype = {
403436 return deferred . promise ;
404437 } ,
405438
439+
406440 // Parse a local model, removing all properties beginning with "$" and
407441 // converting $priority to ".priority".
408442 _parseObject : function ( obj ) {
0 commit comments