@@ -1091,4 +1091,40 @@ $(document).ready(function() {
10911091 equal ( model , doc ) ;
10921092 } ) ;
10931093
1094+ test ( "#walkPath() should not observe Backbone.Models props, only attributes" , function ( ) {
1095+ var nonAttributeChange = sinon . spy ( ) ;
1096+ var changeFromRootModel = sinon . spy ( ) ;
1097+ var changeFromSubModel = sinon . spy ( ) ;
1098+
1099+ var model = new Backbone . NestedModel ( {
1100+ submodel : new Backbone . Model ( { foo : "bar" } )
1101+ } ) ;
1102+
1103+ // submodel.cid is amongst the Backbone.Model fields which should not be observable
1104+ model . bind ( 'change:submodel.cid' , nonAttributeChange ) ;
1105+
1106+ // By defining a new Backbone.Model instance, we're implicitely changing submodel.cid field
1107+ model . set ( "submodel" , new Backbone . Model ( model . get ( "submodel" ) . toJSON ( ) ) ) ;
1108+ sinon . assert . notCalled ( nonAttributeChange ) ;
1109+
1110+ // We should avoid setting sub backbone models watchers directly through model props
1111+ // because it may lead to lots of observers set up on Backbone.Model props
1112+ // particularly _events props which may contain huge objects
1113+ model . bind ( "change:submodel.attributes" , changeFromRootModel ) ;
1114+
1115+ // Trying to update submodel attributes as well... but this should not be allowed either
1116+ // because here, we won't trigger any submodel's event (only model's event)
1117+ // We'll see a better way to handle this below...
1118+ model . set ( "submodel.attributes.foo" , "bar" ) ;
1119+ sinon . assert . calledOnce ( changeFromRootModel ) ;
1120+
1121+
1122+ // We should rather consider binding the change event directly on the submodel
1123+ model . get ( "submodel" ) . bind ( "change:foo" , changeFromSubModel ) ;
1124+
1125+ // This will be far better and will trigger an update this time
1126+ model . get ( "submodel" ) . set ( "foo" , "quix" ) ;
1127+ sinon . assert . calledOnce ( changeFromSubModel ) ;
1128+ } ) ;
1129+
10941130} ) ;
0 commit comments