JavaScript is a playground. If you disagree, then I encourage you to read
Atwood’s Law.
A quick Google search will reveal the law in full force with
assemblers,
machine emulators, and
programming languages
all written in JavaScript. That is just a small sampling. Go peruse the
npm registry for plenty of build tools, frameworks, and
servers written in JavaScript. We are tinkerers, especially in the JavaScript community.
Sometimes our creations are practical and sometimes they are just fun.
With that introduction framing this post, I would like to show off some fun I had with Polymer
and Marionette.js recently.
Web Components and Polymer
Before we dig in, here is a quick rundown of web components and Polymer if you are unsure
what they are.
Web Components as a standard intends to empower web applications to be modular through
native browser technologies. Four specs comprise Web Components: Custom Elements, HTML
Imports, Templates, and the Shadow DOM. Essentially, web components allow developers to
create reusable components with custom HTML elements. The Shadow DOM affords developers
encapsulation of their custom elements via a separate DOM tree that does not bleed into
the containing document. For more information on Web Components, you can visit
webcomponents.org.
Developed by Google, Polymer is a project that aims to simplify defining web components.
To the best of its ability, Polymer also polyfills any functionality not natively
available in the browser (e.g. custom elements, HTML imports, etc.). For more information
on Polymer, you can visit www.polymer-project.org.
Marionette.js Components
Now, back to the topic of this post. I first developed the idea of making Polymer components
play along with Marionette.js for a talk on architecture and components I gave at the inaugural
conference in .* If you would like to watch
my talk, you can view it on YouTube.
Toward the end of my talk, I demoed creating a custom name tag element. Furthermore, I showcased
the ability to wrap that custom element with a custom Marionette view type and keep model data
synced with a regular Marionette ItemView. I would like to go into more detail the steps
I took to create this custom Marionette view type and how I was able to keep model data synced.
Building a Name Tag Element
Our name tag element will be pretty basic, displaying a name and job. We will also be able
to edit the name and job. To build the name tag element, we will use this simple Polymer
convention for creating custom elements:
There are few concepts to explain here. At line 1, we import our framework for defining
a custom element via an import link relation. At line 3, we define our custom element
by wrapping it with a <polymer-element> tag. We define the name of our custom element
via the name attribute. Note that custom elements require at least one hyphen for
their tag name. In other words, we cannot use <nametag>. We also publish attributes
for our custom element with the attributes… ahem, attribute. Publishing attributes
will allow us to set values for properties, which we will see in a second.
At lines 4-9, we define the template for our custom template by wrapping the template
content with a <template> tag. Note the mustache-like syntax to interpolate values for
name and job.
Finally at lines 11-14, we tell Polymer about the properties of our custom element. Note,
they match the attributes we published, and we give them default values.
Now we can use our custom element just like any other HTML element:
Let us take this a step further and now integrate this with Marionette.js. If you are
unfamiliar with Marionette, it is a framework that simplifies Backbone.js application
development. You can learn more at marionettejs.com.
What we want to accomplish is a way to not only instantiate our custom element with
Marionette but to also sync model data with other Marionette views. We will tackle the
former first, allowing us to do this:
As you can see above, our custom Marionette view type is called Marionette.PolymerView.
I have set up a basic GitHub repo for its implementation at
jfairbank/marionette.polymerview.
You can view the source in the below gist too: