@@ -9,24 +9,24 @@ var bbVersion = require( './backbone+' ).VERSION,
99
1010function parseReference ( collectionRef ) {
1111 switch ( typeof collectionRef ) {
12- case 'function' :
13- return collectionRef ;
14- case 'object' :
15- return function ( ) { return collectionRef ; } ;
16- case 'string' :
17- var path = collectionRef
18- . replace ( / \^ / g, 'getOwner().' )
19- . replace ( / ^ \~ / , 'store.' )
20- . replace ( / ^ s t o r e \. ( \w + ) / , 'getStore().get("$1")' ) ;
21-
22- return new Function ( 'return this.' + path ) ;
12+ case 'function' :
13+ return collectionRef ;
14+ case 'object' :
15+ return function ( ) { return collectionRef ; } ;
16+ case 'string' :
17+ var path = collectionRef
18+ . replace ( / \^ / g, 'getOwner().' )
19+ . replace ( / ^ \~ / , 'store.' )
20+ . replace ( / ^ s t o r e \. ( \w + ) / , 'getStore().get("$1")' ) ;
21+
22+ return new Function ( 'return this.' + path ) ;
2323 }
2424}
2525
2626var TakeAttribute = attribute . Type . extend ( {
27- clone : function ( value ) { return value ; } ,
27+ clone : function ( value ) { return value ; } ,
2828 isChanged : function ( a , b ) { return a !== b ; } ,
29- set : function ( value , name ) {
29+ set : function ( value , name ) {
3030 if ( ! value ) return null ;
3131
3232 error . hardRefNotAssignable ( this , name , value ) ;
@@ -35,16 +35,16 @@ var TakeAttribute = attribute.Type.extend( {
3535 _update : function ( val , options , model , attr ) {
3636 return this . delegateEvents ( this . cast ( val , options , model , attr ) , options , model , attr ) ;
3737 }
38- } ) ;
38+ } ) ;
3939
4040exports . take = function ( reference ) {
4141 var getMaster = parseReference ( reference ) ;
4242
43- var options = attribute ( {
44- value : null ,
43+ var options = attribute ( {
44+ value : null ,
4545 toJSON : false ,
46- type : this ,
47- get : function ( ref , name ) {
46+ type : this ,
47+ get : function ( ref , name ) {
4848 if ( ! ref ) {
4949 // Resolve reference.
5050 var value = getMaster . call ( this ) ;
@@ -59,12 +59,44 @@ exports.take = function( reference ){
5959
6060 return ref ;
6161 }
62- } ) ;
62+ } ) ;
6363
6464 options . Attribute = TakeAttribute ;
6565 return options ;
6666} ;
6767
68+ exports . valueLink = function ( reference ) {
69+ var getMaster = parseReference ( reference ) ;
70+
71+ function setLink ( value ) {
72+ var link = getMaster . call ( this ) ;
73+ link && link . requestChanges ( value ) ;
74+ }
75+
76+ function getLink ( ) {
77+ var link = getMaster . call ( this ) ;
78+ return link && link . value ;
79+ }
80+
81+ var LinkAttribute = attribute . Type . extend ( {
82+ createPropertySpec : function ( ) {
83+ return {
84+ // call to optimized set function for single argument. Doesn't work for backbone types.
85+ set : setLink ,
86+
87+ // attach get hook to the getter function, if present
88+ get : getLink
89+ }
90+ } ,
91+
92+ set : setLink
93+ } ) ;
94+
95+ var options = attribute ( { toJSON : false } ) ;
96+ options . Attribute = LinkAttribute ;
97+ return options ;
98+ } ;
99+
68100exports . from = function ( masterCollection ) {
69101 var getMaster = parseReference ( masterCollection ) ;
70102
@@ -91,7 +123,7 @@ exports.from = function( masterCollection ){
91123
92124 if ( master && master . length ) {
93125 // Silently update attribute with object form master.
94- objOrId = master . get ( objOrId ) || null ;
126+ objOrId = master . get ( objOrId ) || null ;
95127 this . attributes [ name ] = objOrId ;
96128
97129 // Subscribe for events manually. delegateEvents won't be invoked.
@@ -107,7 +139,7 @@ exports.from = function( masterCollection ){
107139 }
108140 } ) ;
109141
110- var options = attribute ( { value : null } ) ;
142+ var options = attribute ( { value : null } ) ;
111143 options . Attribute = ModelRefAttribute ; //todo: consider moving this to the attrSpec
112144 return options ;
113145} ;
@@ -116,7 +148,7 @@ var CollectionProto = Collection.prototype;
116148
117149var refsCollectionSpec = {
118150 _listenToChanges : bbVersion >= '1.2.0' ? 'update reset' : 'add remove reset' , // don't bubble changes from models
119- __class : 'Collection.SubsetOf' ,
151+ __class : 'Collection.SubsetOf' ,
120152
121153 resolvedWith : null ,
122154 refs : null ,
@@ -126,9 +158,9 @@ var refsCollectionSpec = {
126158 } ,
127159
128160 clone : function ( options ) {
129- var copy = CollectionProto . clone . call ( this , _ . omit ( options , 'deep' ) ) ;
161+ var copy = CollectionProto . clone . call ( this , _ . omit ( options , 'deep' ) ) ;
130162 copy . resolvedWith = this . resolvedWith ;
131- copy . refs = this . refs ;
163+ copy . refs = this . refs ;
132164
133165 return copy ;
134166 } ,
@@ -153,7 +185,7 @@ var refsCollectionSpec = {
153185 return CollectionProto . toggle . call ( this , model , val ) ;
154186 } ,
155187
156- addAll : function ( ) {
188+ addAll : function ( ) {
157189 this . reset ( this . resolvedWith . models ) ;
158190 } ,
159191
@@ -172,12 +204,12 @@ var refsCollectionSpec = {
172204
173205 getModelIds : function ( ) { return this . refs || _ . pluck ( this . models , 'id' ) ; } ,
174206
175- justOne : function ( arg ) {
207+ justOne : function ( arg ) {
176208 var model = arg instanceof Backbone . Model ? arg : this . resolvedWith . get ( arg ) ;
177209 this . set ( [ model ] ) ;
178210 } ,
179211
180- set : function ( models , upperOptions ) {
212+ set : function ( models , upperOptions ) {
181213 var options = { merge : false } ;
182214
183215 if ( models ) {
@@ -204,7 +236,7 @@ var refsCollectionSpec = {
204236} ;
205237
206238exports . subsetOf = function ( masterCollection ) {
207- var SubsetOf = this . __subsetOf || ( this . __subsetOf = this . extend ( refsCollectionSpec ) ) ;
239+ var SubsetOf = this . __subsetOf || ( this . __subsetOf = this . extend ( refsCollectionSpec ) ) ;
208240 var getMaster = parseReference ( masterCollection ) ;
209241
210242 return attribute ( {
0 commit comments