Writing a Handlebars Template Engine

139 views
Skip to first unread message

mat...@osbornm.com

unread,
Mar 28, 2013, 2:14:56 PM3/28/13
to knock...@googlegroups.com
Hey Everyone, 

I'm looking to write a template engine for Handlebars. I have what I believe is the correct code based on what I can grok from looking at other engines (native, jQuery, and a mustache one posted online), However when rebinding happens (aka I start with placeholder data and make an AJAX call to get the data, and the data comes back and I change the model) the whole Node for the data is re-rendered. This means that when I have a treeview (I wrote myself) and I have a node expanded when the data comes back it collapses that node again (because thats the default state). I did not have this problem when we were using the native template engine and I can't seem to figure out what it is I need to do to reuse nodes in the engine. Here is a GIST with the code for my engine and the handlebars template I am using (I assume form that you can infer any data/model info you need, but if you need to know more let me know) 


Thanks for the help!

Steve Sanderson

unread,
Mar 28, 2013, 2:48:46 PM3/28/13
to knock...@googlegroups.com, mat...@osbornm.com
Hey

One of the great advantages of DOM-based templates (the native mechanism) is that existing DOM nodes remain in use and KO and just mutate those DOM elements without destroying unrelated aspects of their state. String-based template engines suffer from replacing whole areas of the DOM on each change, destroying any state not managed in your viewmodel.

Options:
1. Manage all state in your viewmodel, so that whatever part of the DOM is reconstructed, it comes back in the desired state. This is the MVVM-pure approach, but sometimes it's highly inconvenient.
2. Or, split your template into nested subtemplates, and then use the "template" binding to render each nested template. KO will only re-render the innermost nested template that is affected by a viewmodel change, so other DOM state will be preserved. This was the best approach before KO got its native DOM-based template engine in version 2.0.
3. Or, use KO's native DOM-based template engine, where it already is able to preserve unrelated DOM state :)

I guess you have some reason not to do #3, otherwise you would already be doing so. But could you clarify the use case? String-based templates are just not as convenient in general.

Steve

mat...@osbornm.com

unread,
Mar 28, 2013, 3:29:39 PM3/28/13
to knock...@googlegroups.com, mat...@osbornm.com
Hey Steve,

Thanks for the quick reply! We are currently using the Default DOM based templates and they are working great. The reason I started exploring other options was that on our team I was seeing an influx of logic in the template (Lots of if statements and virtual elements) themselves and I was looking for a template type that would prevent this type of logic inherently. Thats what lead me down the road of Handlebars. Additionally as I looked into it more I felt that the placing the text in the correct places in that markup was just "more natural" then in the data-bind attribute. However, ther fact that lots of nodes will be created and destroyed is a huge reason to go back to #3. 

What are you thoughts on a more "natural" location for things like text and html? Seems weird having it all crammed into the data-bind attribute. Maybe it's not that important and I'm just being silly?

Cheers,
Matthew M. Osborn

rpn

unread,
Mar 28, 2013, 3:37:23 PM3/28/13
to knock...@googlegroups.com, mat...@osbornm.com
Matthew-
One thing that you could consider is how you might be able to leverage the custom binding provider extensibility feature in Knockout.  This allows you to take control of how bindings are parsed on an element.  For example, here is an implementation that places the actual binding definitions into a JavaScript object and keys into them from the markup: https://github.com/rniemeyer/knockout-classBindingProvider.   I am not suggesting using it in conjunction with Handlerbars, but just as an option that could could explore to take better control over what is placed in the markup.

-Ryan

dotn...@gmail.com

unread,
Mar 28, 2013, 5:51:48 PM3/28/13
to knock...@googlegroups.com, mat...@osbornm.com
Is it safe to assume that a string-based approach, even if you kept all state information in your view model, would potentially suffer from performance issues related to constantly replacing the DOM elements? I'm thinking about a common scenario today where you might enable/disable submit buttons based on validation rules (like required fields). In the native engine, things only swap when KO detects they should, whereas with Matthew's engine, you'd be forced to re-render and replace the whole bound section of the page, right?


On Thursday, March 28, 2013 11:48:46 AM UTC-7, Steve Sanderson wrote:

mat...@osbornm.com

unread,
Mar 28, 2013, 5:54:03 PM3/28/13
to knock...@googlegroups.com, mat...@osbornm.com, dotn...@gmail.com
In my case it would find the closest template and rebind that so if the closest template was the whole page then yes.

rpn

unread,
Mar 28, 2013, 5:57:17 PM3/28/13
to knock...@googlegroups.com, mat...@osbornm.com, dotn...@gmail.com
In a string-based engine in KO, you can still use "data-bind" bindings along with whatever the templating provides, which would behave as you would expect.  The entire template would not be re-rendered as a result of an element's binding firing, unless that observable was also referenced elsewhere as part of the template libraries output.  So, anything accessed through the templating libraries "normal" syntax would become dependencies of the entire template and cause it to be re-rendered.

Brad Wilson

unread,
Mar 28, 2013, 5:58:36 PM3/28/13
to rpn, knock...@googlegroups.com, Matthew Osborn
Meh, I think in that case I'd prefer to just stick with the built-in engine. The whole point of using Handlebars would be to get the more compact, non-data-bind syntax.
Reply all
Reply to author
Forward
0 new messages