|
889 | 889 | } |
890 | 890 | }, |
891 | 891 |
|
| 892 | + // Return model's value for dot-separated 'deep reference'. |
| 893 | + // Model id and cid are allowed for collection elements. |
| 894 | + // If path is not exist, 'undefined' is returned. |
| 895 | + // model.deepGet( 'a.b.c123.x' ) |
892 | 896 | deepGet : function( name ){ |
893 | | - var path = name.split( '.' ), |
894 | | - l = path.length, |
895 | | - value = this; |
| 897 | + var path = name.split( '.' ), value = this; |
896 | 898 |
|
897 | | - for( var i = 0; value && i < l; i++ ){ |
| 899 | + for( var i = 0, l = path.length; value && i < l; i++ ){ |
898 | 900 | value = value.get ? value.get( path[ i ] ) : value[ path[ i ] ]; |
899 | 901 | } |
900 | 902 |
|
901 | 903 | return value; |
902 | 904 | }, |
903 | 905 |
|
| 906 | + // Set model's value for dot separated 'deep reference'. |
| 907 | + // If model doesn't exist at some path, create default models |
| 908 | + // if options.nullify is given, assign attributes with nulls |
904 | 909 | deepSet : function( name, value, options ){ |
905 | 910 | var path = name.split( '.' ), |
906 | 911 | l = path.length - 1, |
907 | 912 | model = this, |
908 | 913 | attr = path[ l ]; |
909 | 914 |
|
910 | 915 | for( var i = 0; i < l; i++ ){ |
911 | | - var next = model.get ? model.get( path[ i ] ) : model[ path[ i ] ]; |
| 916 | + var current = path[ i ], |
| 917 | + next = model.get ? model.get( current ) : model[ current ]; |
| 918 | + |
| 919 | + // Create models in path, if they are not exist. |
912 | 920 | if( !next ){ |
913 | | - if( model.defaults ){ |
914 | | - var newModel = model.__attributes[ path[ i ] ].create(); |
915 | | - if( options && options.nullify && newModel.defaults ){ |
916 | | - var nulls = newModel.defaults(); |
917 | | - _.each( nulls, function( spec, name ){ |
918 | | - nulls[ name ] = null; |
919 | | - }); |
| 921 | + var attrSpecs = model.__attributes; |
| 922 | + |
| 923 | + if( attrSpecs ){ |
| 924 | + // If current object is model, create default attribute |
| 925 | + var newModel = attrSpecs[ current ].create( options ); |
| 926 | + |
| 927 | + // If created object is model, nullify attributes when requested |
| 928 | + if( options && options.nullify && newModel.__attributes ){ |
| 929 | + var nulls = new newModel.Attributes( {} ); |
| 930 | + for( var key in nulls ) nulls[ key ] = null; |
920 | 931 | newModel.set( nulls ); |
921 | 932 | } |
922 | | - model.set( path[ i ], newModel ); |
923 | | - next = model.get( path[ i ] ); |
924 | | - }else{ |
925 | | - return; |
| 933 | + |
| 934 | + model[ current ] = next = newModel; |
926 | 935 | } |
| 936 | + else return; // silently fail in other case |
927 | 937 | } |
928 | 938 | model = next; |
929 | 939 | } |
|
0 commit comments