I have a deadline for the alpha release for Dart for Hipsters, but before I can get to that, I must appease the gods of my chain. I have yet to meet these gods, but they have been kind to me, so I must do what I can to keep them happy.
Last night I got started breaking my Ajax based Dart application into real View classes (somewhat along the lines of Backbone.js). Today, I hope to extract collection code from my view into a proper collection class.
The heart of the collection, the fetching from the backend datastore, I can already do:
class ComicsCollection {
  var list;
  ComicsCollection() {
  }
  // Be Backbone like
  fetch() {
    var req = new XMLHttpRequest();
    req.on.load.add(_handleOnLoad);
    req.open('get', '/comics', true);
    req.send();
  }
  _handleOnLoad(event) {
    var request = event.target;
    list = JSON.parse(request.responseText);
    // How to tell the view that I'm done?
  }
}But how can I communicate to my view that the collection has loaded new data? I would like to instantiate a collection and a collection view something along the lines of:
  var my_comics_collection = new ComicsCollection()
    , comics_view = new ComicsCollectionView(
        el:'#comics-list',
        collection: my_comics_collection
      );
  my_comics_collection.fetch();In the collection view, I could then subscribe to the collection view's on-load event:  ComicsCollectionView([el, collection]) {
    this.el = document.query(el);
    this.collection = collection;
    collection.on.load.add((event) {
      render();
    });
  });To get that to work, I will at least need an on getter in the Collection:class ComicsCollection {
  var list;
  var get on;
  ComicsCollection() {
    on = new CollectionEvents();
  }
}I could probably re-use one of the DOM Events classes here, but it is not too hard to define my own:class CollectionEvents implements Events {
  var load_list;
  CollectionEvents() {
    load_list = new CollectionEventList();
  }
  get load() {
    return load_list;
  }
}I defined a load getter that returns an EventList object. This CollectionEventList class that I define will be the thing that holds event listeners.  It needs to define two methods: add() to add listeners and dispatch() to send events to all listeners:class CollectionEventList implements EventListenerList {
  var listeners;
  CollectionEventList() {
    listeners = [];
  }
  add(fn) {
    listeners.add(fn);
  }
  bool dispatch(Event event) {
    listeners.forEach((fn) {fn(event);});
    return true;
  }
}No doubt I can be a little more elegant about that, but that should meet the spirit of what is needed. Amazingly, that does work.  To be sure that I am not somehow faking it, I add another debugging on-load handler to listen for my custom event:class ComicsCollectionView {
  var get el;
  var get collection;
  ComicsCollectionView([el, collection]) {
    this.el = document.query(el);
    this.collection = collection;
    collection.on.load.add((event) {
      render();
    });
    collection.on.load.add((event) {
      print("This really did fire in response to a custom event");
    });
    _attachUiHandlers();
  }
  // ...
}And indeed, it does work:Nice. That almost seems a little too easy. I will take a look at this in the fresh light of a new day to make sure that I am not cheating somehow. If custom event handlers in Dart really are this easy, then I am thrilled. Bust mostly I'm sleepy.
Day #282





















