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