One-way data binding

28 views
Skip to first unread message

benbriedis

unread,
May 11, 2018, 2:51:09 AM5/11/18
to Nunjucks
Hi everyone,

I would like to use one-way data binding with Nunjucks and I am looking at different approaches.  This is an important issue as responsive single-page apps are in vogue and the more static-page inclined templating languages are being left behind, which is a shame as they are clean, powerful and simple.


Sadly at the moment most approaches seem a bit deficient, but I think the situation could be remedied (more on this below).  The approaches methods I've found are:

1. Separate out every chunk of code that may to be re-rendered into a separate file so it can be rendered separately.  Write some controller some to ensure that these small templates are rendered as required and inserted into the DOM using placeholders in the code, or possibly using selectors.  This is a fussy approach and is likely to lead to having many small templates.

2. Re-render whole pages or large chunks of code. Obviously not ideal.

3. Use Javascript to handle all the dynamic stuff. A library such as this could be used: https://github.com/remy/bind.js  Doing this means we don't get to use Nunchuck's loops etc. It's a hybrid approach.

4. Similarly we could embed Vue.js or similar, but then we have two templating languages instead of one.

5. We could use this extension: https://github.com/chandlerprall/DatabindExtension that implements a "bind" tag.

I've been looking at the last option recently and it comes close to being a reasonable solution.  The README doesn't mention it but is possible to access objects within objects and array elements.  Array elements are fussy though due to the way Nunjucks binds loop variables. For it to work you need to:

a) Construct tags this way: {% bind "address."+i %}  (which is OK) and
b) Place the contents of the loop (excluding the "for" tags) within a macro and calling the macro  (which is a bit nasty)

If the loop binding issue in Nunjucks were fixed then the extension would be a pretty good solution for data binding.  As it is, the solution is a bit cludgy - but probably the best approach nonetheless.

Beyond that I think a reasonable solution might be to provide the renderer with a list of nodes in the data structure that can be modified in the future.  This could be done using simplified a XPath-style syntax - e.g.
        addresses
        addresses[]
        addresses[].name  etc
The renderer would add markers or placeholders into the DOM at nodes that use the specified data during the first render.  For subsequent changes a "rerender" function could be called and it could provide one these paths to indicate what has changed. A nice thing about this approach is that the template would not require any explicit bindings!

I'm wondering whether anyone would have any appetite for making any of these changes (either to better support DatabindExtension or provide the more ambitious change) or would be able to provide any advice or assistance should I choose to.

Cheers,
Ben


Reply all
Reply to author
Forward
0 new messages