I forked the Github repository and issued a pull request. I'll try to remember to include a link here when I get around to deploying it on App Engine.
But I dreaded the idea of having to reproduce the entire project for each REST API - or, more accurately, service - for which I want to provide a browser UI. So the task became how to minimize the repetition involved in creating a CRUD client for an API service. Note that the concept of web services isn't exactly required at this point in our discussion. The data could also come from a local file or AJAX request.
Subclassing Polymer custom components
At the 0.5 milestone, Polymer supports the subclassing of custom components. What this means, exactly, is somewhat unclear, as evidenced by the dropping of its support in the 1.0 release. But I was intrigued with the possibility of abstracting out the CRUD boilerplate and getting some nifty custom web component polymorphism action. I was somewhat successful.
First came the task of determining what the base class(es) would contain. All conceivable, at least to me, interactions with a collection of objects consist of our basic CRUD operations. Therefore, a base class called ItemElement was created. ItemElement would consist of the following:
- An instance of the model class Item, item
- Stubs, at least, for the CRUD methods read() and update()
- A list of Item instances, items
- Stubs, at least, for the CRUD methods create() and delete()
With the success of this basic refactoring, I have stepped back to consider what to do next. Some targets are obvious, such as the difficulty in controlling the placement of HTML elements in the Codelab components. When a base class contains HTML elements, interspersing HTML elements into them from within subclass components is tricky and largely undocumented outside of a brief discussion of the <content> and <shadow> elements on the Polymer website. One is left with the idea that a great deal of flexibility can be leveraged from these. But how?
The next candidate for refactoring consists of removing the form classes ItemForm and CodelabForm contained in the files item_form.[dart/html] and codelab_form.[dart/html] It looks to me that these four files can be easily eliminated from the project by factoring their contents into the ItemElement class. Since the custom Polymer component <item-element> contains logic to control the display of an item based on whether it is being edited, the <item-form> component appears to be at best a convenient abstraction and at worst a design flaw.
Finally, adding the calls to a Codelab web service is on this list of enhancements. This presents particularly attractive possibilities for refactoring. Initial experiments indicate that large portions of the REST API interaction can live in the base classes ItemElement and ItemList. This should be most enjoyable and I expect to report back how Dart made doing this a pleasure.