I made it through a chunk of refactoring in my Dart based minimal MVC framework yesterday. I am still not quite done, however. My ultimate goal is to reach a point at which adding to a collection will fire an event for which a collection view can listen and react.
As of last night, I have a view that creates a new model on the collection using the
create() method in the HipsterCollection base class:class HipsterCollection {
// ...
create(attrs) {
var new_model = model(attrs);
new_model.save(callback:(event) {
this.add(new_model);
});
}
add(model) {
models.add(model);
on.add.
dispatch(new CollectionEvent('add', this, model:model));
}
// ...
}After a new model is saved, it is added to the collection. The add() method also dispatches an add event, for which the collection view can listen:#library('Collection View for My Comic Book Collection');
#import('HipsterView.dart');
class Comics extends HipsterView {
Comics([collection, model, el]):
super(collection:collection, model:model, el:el);
post_initialize() {
_subscribeEvents();
// ...
}
_subscribeEvents() {
if (collection == null) return;
collection.on.load.add((event) { render(); });
collection.on.add.add((event) { render(); });
}
// ...
}The add.add thing is a little weird (add an event listener for the add event). Since I am defining these events myself, I will have to come up with a better name. But, for now, it works. When I add couple of test comic books to my collection, they are immediately added to the UI:Yay!
That was sort of anti-climatic. I have struggled much getting to this point. I did not expect it to just work. Ah well.
There is a minor problem. I cannot delete the newly added comic books. This turns out to be due to a lack of ID, which I add to the enclosing
<li> tag:If I reload the page, the new items have an ID and I can delete them. So something must be going wrong in the model creation. Looking at the
save() method in my HipsterModel, I think I see what. I am not adding the response from the server to the internal attributes:class HipsterModel {
// ...
save([callback]) {
var req = new XMLHttpRequest()
, json = JSON.stringify(attributes);
req.on.load.add((event) {
print("[save] ${req.responseText}");
on.save.dispatch(event);
if (callback != null) callback(event);
});
print("[save] $json");
req.open('post', '/comics', true);
req.setRequestHeader('Content-type', 'application/json');
req.send(json);
}
// ...
}I print the response to the console, but I am not doing anything with it. And, indeed, the response does contain the ID from the server:It is easy enough to parse that JSON response so that the model's attributes can be updated accordingly:
class HipsterModel {
// ...
save([callback]) {
var req = new XMLHttpRequest()
, json = JSON.stringify(attributes);
req.on.load.add((event) {
attributes = JSON.parse(req.responseText);
on.save.dispatch(event);
if (callback != null) callback(event);
});
req.open('post', '/comics', true);
req.setRequestHeader('Content-type', 'application/json');
req.send(json);
}
// ...
}
With that, I can add comics to my collection, have them show up on the page, and delete them. And all of this is reflected in the backend datastore:That is a fine stopping point for tonight. There is still a ton to do before I am even close to replicating something like Backbone.js in Dart (and I have no intention of doing that), but I feel as though I am off to a pretty solid start. I am especially pleased with how easy it was to achieve the same separation of concerns through events that Backbone boasts.
Up tomorrow: I make my minimal framework a little more Dart-like starting with exploring Generics.
Day #291




No comments:
Post a Comment