Learning Angular 2 Beta has been a non-trivial effort. As I described it on the Adventures in Angular podcast, it's a bit like having a stroke and needing to relearn everything you think you knew about AngularJS application development. Part of what makes it hard to learn is that I'm not using it in production yet; so, I don't get to leverage the continual daily exposure that I'd normally get at work. To make up for this, I try to build little demo components that give my research and development (R&D) some direction.
A couple of months ago, in a Twitter conversation, Todd Motto had suggested that a great learning exercise is trying to build a dropdown menu component. This is something that I've done in the past, using AngularJS 1.x; and, I totally agree - it's a fairly small yet sufficiently complex task. So, I set about trying to create an HTML dropdown menu in Angular 2 Beta.
I started this exercise in Beta 1 and I finally finished it in Beta 11. This was not due to laziness - this was due to complexity. Every time that I tried to move forward on this component, I stumbled over some new feature or caveat of Angular 2 that took me on a tangential learning adventure. If I had to guess, I'd say that a good third of the blog posts that I've written on Angular 2 were in an effort to move closer to an HTML dropdown menu solution.
The goal of this component was to be able to let the user provide arbitrary HTML markup for the items in the options menu. This was done through inter-component communication in which the HtmlMenuItem components exposed their ElementRef values to the HtmlMenu component upon request. The HtmlMenu component then used the BrowserDomAdapter to render the selected HtmlMenuItem component as HTML in the menu root.
Because I am quite tired today; and, because this post is really just an aggregation of many other post that I've written, I'm going to offer up the code without much additional explanation. Take this as you will. I've tried to leave lots of relevant comments in the code.
As you can see, building an HTML dropdown menu is a really wonderful learning exercise because it is fairly small (less than 1,000 lines of code) and yet very complex. It touches upon so many aspects of Angular 2 - ngModel, change detection, inputs, outputs, HTML projection, inter-component communication, life-cycle event methods, one-way data flow constraints, providers, sibling directives, transclusion (ie, content projection), host bindings, view rendering, etc.. There's a lot of stuff here, chockfull of complexity and subtlety.
Want to use code from this post? Check out the license.