Having addressed a minor Dart-to-Javascript mystery, I am ready to dive back into my rudimentary MVC framework. Up tonight: collections.
I can factor just about everything that I previously had in my
ComicsCollection class out into a base class. This leaves behind something like:#library('Collection class to describe my comic book collection');
#import('HipsterCollection.dart');
#import('Models.ComicBook.dart');
class Comics extends HipsterCollection {
Comics() {
url = '/comics';
model = ComicBook;
on = new CollectionEvents();
models = [];
}
}The on and models object properties ought to get pushed into the base class as well. I will worry about that another time. For now I would like to make sure that the url and model properties are working.The
url property is pretty straight-forward. I am only using it to fetch() a collection of models. There is nothing too fancy there:#library('Base class for Collections');
#import('dart:html');
#import('dart:htmlimpl');
#import('dart:json');
class HipsterCollection {
var url, model, models, on;
//...
fetch() {
var req = new XMLHttpRequest();
req.on.load.add(_handleOnLoad);
req.open('get', url, true);
req.send();
}
}What is fancy (well, relatively speaking) is the instantiation of models for the collection. Since I am setting the model = ComicBook in my collection class, I would like to create the models something like this:class HipsterCollection {
var url, model, models, on;
// ....
_handleOnLoad(event) {
var request = event.target
, list = JSON.parse(request.responseText);
list.forEach((attrs) {
models.add(new model(attrs));
});
on.load.dispatch(new Event('load'));
}
}The only problem is that Dart does not care for the model = ComicBook assignment:Internal error: 'http://localhost:3000/scripts/Collections.Comics.dart': Error: line 9 pos 13: Unresolved identifier 'Library:'http://localhost:3000/scripts/Models.ComicBook.dart' Class: ComicBook'
model = ComicBook;
^I spend a bit of time rooting around for ways to create classes from strings and the like in Dart, but come up empty. I also try static class methods:class HipsterModel {
static constructor() {
// construct things
}
//...
}But, when I try to assign that to my model attribute:class Comics extends HipsterCollection {
Comics() {
url = '/comics';
model = ComicBook.constructor;
//...
}
}I am greeted with another error:Internal error: 'http://localhost:3000/scripts/Collections.Comics.dart': Error: line 9 pos 23: unknown static field 'constructor'
model = ComicBook.constructor;
^Eventually, I settle on a constructor function:class Comics extends HipsterCollection {
Comics() {
url = '/comics';
model = (attrs) => new ComicBook(attrs);
// ...
}
}I may not be able to assign class names or static methods, but I can assign anonymous functions. In the HipsterCollection base class, I can then create new models like this:class HipsterCollection {
var url, model, models, on;
// ....
_handleOnLoad(event) {
var request = event.target
, list = JSON.parse(request.responseText);
list.forEach((attrs) {
models.add(model(attrs));
});
on.load.dispatch(new Event('load'));
}
}
That is somewhat unsatisfying because my base class looks prettier than my sub-class. If I stick with this implementation, I will probably have to rename the model attribute to something like model_constructor. More bothersome than a long attribute name how verbose it has to be when I only want to describe that the model being collected is a ComicBook. Day #289
Wouldn't it be much easier to use generics here: https://gist.github.com/1778137, or I missed something here?
ReplyDeleteInteresting. That very well may be the "Dart way" to accomplish what I want. I had only thought of generics as a way to constrain values and definitely had not realized that you can use them to create new instances of the thing. That's a nice little trick.
DeleteI will definitely play around with this. I wonder if T would be ComicBook if I sub-classed HipsterCollection as: `class Comics<ComicBook> extends HipsterCollection`. If it does, then problem solved.
Regardless, I am excited about this application of generics. Thanks for pointing it out!
I tried this (http://japhr.blogspot.com/2012/02/generic-constructors-in-dart.html), but it seems constructing from generic type information is not currently allowed :-(
Delete