@@ -1117,4 +1117,40 @@ $(document).ready(function() {
11171117 equal ( model , doc ) ;
11181118 } ) ;
11191119
1120+ test ( "#walkPath() should not observe Backbone.Models props, only attributes" , function ( ) {
1121+ var nonAttributeChange = sinon . spy ( ) ;
1122+ var changeFromRootModel = sinon . spy ( ) ;
1123+ var changeFromSubModel = sinon . spy ( ) ;
1124+
1125+ var model = new Backbone . NestedModel ( {
1126+ submodel : new Backbone . Model ( { foo : "bar" } )
1127+ } ) ;
1128+
1129+ // submodel.cid is amongst the Backbone.Model fields which should not be observable
1130+ model . bind ( 'change:submodel.cid' , nonAttributeChange ) ;
1131+
1132+ // By defining a new Backbone.Model instance, we're implicitely changing submodel.cid field
1133+ model . set ( "submodel" , new Backbone . Model ( model . get ( "submodel" ) . toJSON ( ) ) ) ;
1134+ sinon . assert . notCalled ( nonAttributeChange ) ;
1135+
1136+ // We should avoid setting sub backbone models watchers directly through model props
1137+ // because it may lead to lots of observers set up on Backbone.Model props
1138+ // particularly _events props which may contain huge objects
1139+ model . bind ( "change:submodel.attributes" , changeFromRootModel ) ;
1140+
1141+ // Trying to update submodel attributes as well... but this should not be allowed either
1142+ // because here, we won't trigger any submodel's event (only model's event)
1143+ // We'll see a better way to handle this below...
1144+ model . set ( "submodel.attributes.foo" , "bar" ) ;
1145+ sinon . assert . calledOnce ( changeFromRootModel ) ;
1146+
1147+
1148+ // We should rather consider binding the change event directly on the submodel
1149+ model . get ( "submodel" ) . bind ( "change:foo" , changeFromSubModel ) ;
1150+
1151+ // This will be far better and will trigger an update this time
1152+ model . get ( "submodel" ) . set ( "foo" , "quix" ) ;
1153+ sinon . assert . calledOnce ( changeFromSubModel ) ;
1154+ } ) ;
1155+
11201156} ) ;
0 commit comments