Skip to content

Commit 28747ee

Browse files
author
Vlad Balin
committed
Nested.valueLink
1 parent 5232dfd commit 28747ee

File tree

3 files changed

+124
-56
lines changed

3 files changed

+124
-56
lines changed

nestedtypes.js

Lines changed: 62 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ _.extend( exports, Backbone, {
2929
return attribute( { value : value } );
3030
},
3131

32+
valueLink : relations.valueLink,
33+
3234
Collection : Collection,
3335
Model : Model,
3436
Store : Store.Model,

src/relations.js

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,24 @@ var bbVersion = require( './backbone+' ).VERSION,
99

1010
function 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( /^store\.(\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( /^store\.(\w+)/, 'getStore().get("$1")' );
21+
22+
return new Function( 'return this.' + path );
2323
}
2424
}
2525

2626
var 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

4040
exports.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+
68100
exports.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

117149
var 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

206238
exports.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

Comments
 (0)