Skip to content

Commit 235097a

Browse files
committed
making it easier to overwrite model behavior
1 parent 251be5f commit 235097a

File tree

3 files changed

+114
-30
lines changed

3 files changed

+114
-30
lines changed

control/control.html

+6-6
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,18 @@
3939
<body>
4040
<div id="demo-html">
4141
<ul id="tabs" class="tabs ui-helper-clearfix">
42-
<li><a href="#tab1">Tab 1</a></li>
43-
<li><a href="#tab2">Tab 2</a></li>
44-
<li><a href="#tab3">Tab 3</a></li>
42+
<li><a href="#tab1">Model</a></li>
43+
<li><a href="#tab2">View</a></li>
44+
<li><a href="#tab3">Controller</a></li>
4545
</ul>
4646
<div id="tab1" class="tab">
47-
Tab 1 Content
47+
Model Content
4848
</div>
4949
<div id="tab2" class="tab">
50-
Tab 2 Content
50+
View Content
5151
</div>
5252
<div id="tab3" class="tab">
53-
Tab 3 Content
53+
Controller Content
5454
</div>
5555
</div>
5656
<script type="text/javascript" src="../../steal/steal.js"></script>

model/model.js

+32-24
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ steal('can/observe', function() {
9696
/**
9797
* @Static
9898
*/
99-
ajaxMethods = {
99+
//
100100
/**
101101
* @function bind
102102
* `bind(eventType, handler(event, instance))` listens to
@@ -153,6 +153,7 @@ steal('can/observe', function() {
153153
* id: "Id"
154154
* },{});
155155
*/
156+
ajaxMethods = {
156157
/**
157158
* @function create
158159
* `create(attributes) -> Deferred` is used by [can.Model::save save] to create a
@@ -172,7 +173,7 @@ steal('can/observe', function() {
172173
* new Recipe({name: "hot dog"}).save();
173174
*
174175
*
175-
* ## Implmeent with a Function
176+
* ## Implement with a Function
176177
*
177178
* You can also implement create by yourself. Create gets called
178179
* with `attrs`, which are the [can.Observe::serialize serialized] model
@@ -543,30 +544,24 @@ steal('can/observe', function() {
543544
if(this === can.Model){
544545
return;
545546
}
546-
var self = this;
547-
547+
var self = this,
548+
clean = can.proxy(this._clean, self);
549+
548550
can.each(ajaxMethods, function(method, name){
549551
if ( ! can.isFunction( self[name] )) {
550552
self[name] = ajaxMaker(method, self[name]);
551553
}
554+
if (self["make"+can.capitalize(name)]){
555+
var newMethod = self["make"+can.capitalize(name)](self[name]);
556+
can.Construct._overwrite(self, base, name,function(){
557+
this._super;
558+
self._reqs++;
559+
return newMethod.apply(self, arguments).then(clean, clean);
560+
})
561+
}
552562
});
553-
var clean = can.proxy(this._clean, self);
554-
can.each({findAll : "models", findOne: "model"}, function(method, name){
555-
556-
var old = self[name];
557-
can.Construct._overwrite(self, base, name, function(params, success, error){
558-
// this._super to trick it to load super
559-
this._super;
560-
// Increment requests.
561-
self._reqs++;
562-
// Make the request.
563-
return pipe( old.call( this, params ),
564-
this,
565-
method ).then(success,error).then(clean, clean);
566-
});
567-
})
568-
// Convert `findAll` and `findOne`.
569-
var oldFindAll
563+
564+
570565
if(self.fullName == "can.Model"){
571566
self.fullName = self._shortName = "Model"+(++modelNum);
572567
}
@@ -673,9 +668,9 @@ steal('can/observe', function() {
673668
return;
674669
}
675670

676-
if ( instancesRawData instanceof this.List ) {
677-
return instancesRawData;
678-
}
671+
if ( instancesRawData instanceof this.List ) {
672+
return instancesRawData;
673+
}
679674

680675
// Get the list type.
681676
var self = this,
@@ -1022,6 +1017,19 @@ steal('can/observe', function() {
10221017
}
10231018
});
10241019

1020+
1021+
1022+
1023+
can.each({makeFindAll : "models", makeFindOne: "model"}, function(method, name){
1024+
can.Model[name] = function(oldFind){
1025+
return function(params, success, error){
1026+
return pipe( oldFind.call( this, params ),
1027+
this,
1028+
method ).then(success,error)
1029+
}
1030+
};
1031+
});
1032+
10251033
can.each([
10261034
/**
10271035
* @function created

model/model_test.js

+76
Original file line numberDiff line numberDiff line change
@@ -641,4 +641,80 @@ test("templated destroy", function(){
641641
new MyModel({id: 5}).destroy(function(){
642642
start();
643643
})
644+
});
645+
646+
test("overwrite makeFindAll", function(){
647+
648+
var store = {};
649+
650+
var LocalModel = can.Model({
651+
makeFindOne : function(findOne){
652+
return function(params, success, error){
653+
var def = new can.Deferred(),
654+
data = store[params.id];
655+
def.then(success, error)
656+
// make the ajax request right away
657+
var findOneDeferred = findOne(params);
658+
659+
if(data){
660+
var instance= this.model(data);
661+
findOneDeferred.then(function(data){
662+
instance.updated(data)
663+
}, function(){
664+
can.trigger(instance,"error", data)
665+
});
666+
def.resolve(instance)
667+
} else {
668+
findOneDeferred.then(can.proxy(function(data){
669+
var instance= this.model(data);
670+
store[instance[this.id]] = data;
671+
def.resolve(instance)
672+
}, this), function(data){
673+
def.reject(data)
674+
})
675+
}
676+
return def;
677+
}
678+
}
679+
},{
680+
updated : function(attrs){
681+
can.Model.prototype.updated.apply(this, arguments);
682+
store[this[this.constructor.id]] = this.serialize();
683+
}
684+
});
685+
686+
687+
can.fixture("/food/{id}", function(settings){
688+
689+
return count == 0 ? {
690+
id: settings.data.id,
691+
name : "hot dog"
692+
} : {
693+
id: settings.data.id,
694+
name : "ice water"
695+
}
696+
})
697+
var Food = LocalModel({
698+
findOne : "/food/{id}"
699+
},{});
700+
stop();
701+
var count = 0;
702+
Food.findOne({id: 1}, function(food){
703+
count = 1;
704+
ok(true, "empty findOne called back")
705+
food.bind("name", function(){
706+
ok(true, "name changed");
707+
equal(count, 2, "after last find one")
708+
equals(this.name, "ice water");
709+
start();
710+
})
711+
712+
Food.findOne({id: 1}, function(food2){
713+
count = 2;
714+
ok(food2 === food, "same instances")
715+
equals(food2.name, "hot dog")
716+
})
717+
})
644718
})
719+
720+

0 commit comments

Comments
 (0)