Creating and reusing custom elements with jQuery vs Polymer vs Dust.js - javascript

I've written some widgets to use in my web app, and I'd like to be able to plug these widgets in throughout the app without pasting big chunks of widget code. So far I've been writing custom HTML tags and using jQuery selectors and CSS to populate and style my tags. The end result allows me to write <myTag></myTag> anywhere on a page, and have my custom widget appear.
Recently, I've learned about Dust JS and Google's Polymer Project. My understanding is that Dust would allow me to write a template and "swap out" parts of the template with my content, while Polymer would allow me to create custom HTML tags as I've been trying to do and place them wherever I'd like.
Would it benefit me to use Dust or Polymer? What is the difference between those two options and simply using jQuery to select my tags and plug in my widget/styles? Obviously these are three drastically different libraries/frameworks, but it seems to me that there is some overlap when it comes to my use case. Please correct me if I'm wrong.
Edit: Say I have a plain old HTML page. The question I'm getting at is what would prevent me from using {myCustomWidget} in Dust to "plug in" my widget throughout the app, other than the fact that this may not be standard usage? Similarly, why would I use Polymer to create "shortcuts" for my widgets over using a jQuery selector?
Thanks!

I don't know a ton about Dust, but I've made fairly heavy use of both jQuery and Polymer. Someone with more Dust experience should totally weigh in. It looks like one of the main advantages of Dust is that it's designed for efficient server-side rendering. It's also format agnostic whereas jQuery and Polymer are both specialized for HTML.
Polymer is designed for the use case of creating encapsulated widgets that can be easily reused. It's got a few advantages over rolling your own system with jQuery:
A Polymer element can be imported with one line, and the import will pull in its html, js, and css, and it will register the element within the page.
Polymer has support for data binding, meaning that you typically don't have to write code to ensure that the widget is updated after some data changes. When the data changes, all of the widgets that are interacting with that respond immediately and automatically.
Polymer interops really well with jQuery, so if you've got a site that's doing a lot of jQuery style interaction today you can gradually introduce Polymer elements and they'll play well with the rest of your page. e.g.
$('<my-slider>').appendTo('body') // append the slider widget to the page
$('my-slider').attr('value') // get the current value of the slider
$('my-slider').attr('value', 100) // set the value of all sliders
etc
The styling of a polymer element is encapsulated, meaning that a widget will not mess up the rest of the page with its CSS, and the enclosing page won't mess up the styling of the widget (though the enclosing page can style the widget it has to be fairly intentional, just setting something like * { padding: 5px; } won't throw everything off).
There's great docs at http://www.polymer-project.org/ (and after getting started, I strongly recommend the API docs, they're quite complete and informative: http://www.polymer-project.org/docs/polymer/polymer.html )

I've not used Polymer before but I've used Dust and jQuery extensively.
Dust is simply a template library, just like Handlebars,Mustache, Twig and the myriad of other template libraries out there. It's written in javascript and can be used with NodeJS or can easily run in the browser if you're building client side applications.
Both Dust and jQuery can be used together. Dust would render your HTML templates and as always, jQuery would be used to manipulate them and do whatever else you normally do with jQuery such as listen to events and handle them accordingly.
It's important to note that the two aren't alternatives but rather they work together. Dust cannot do the things that jQuery does and is not meant to. Dust works very well when you have large templates that require partials and blocks.

At its core, Polymer is a platform of polyfills for the current implementation of the WC3 web component recommendation as well as some aspects of ECMA 6 such as Object.observe() and WeakMap. Included in the Platform are the libraries NodeBind and TemplateBinding which enable observable (two-way) custom element data-binding.
Dustjs is an asynchronous logic-less templating engine for client-side and server-side(Nodejs)
rendering. There is no native concept of an observable in Dustjs(as is the case for most template engines), meaning two-way data-binding is outside the scope of the project. However, the PayPal roadmap for Dustjs indicates two-way data-binding may receive official support by the end of 2014.
That being said, NodeBind and observe-js are separate repos not necessarily tied to the Polymer custom element implementation, meaning you can use them in your own projects--which is exactly what I did.
My biggest criticism of client-side rendering frameworks like Polymer (and in some respects, angularjs), is that they are not SEO compatible. So I actually combined NodeBind with Dustjs to make my own two-way data-bound custom element implementation derived from the Polymer platform. The idea is that Dustjs renders the template server-side(or even client-side, if SPA) and then upon rendering, you bind the Dust context to an observable and then parse the template fragment for attributes and keys, binding them to a path observer which maps to the observable. So, the bulk of the task is to write your own parser. The good news is that you can use the Dust parser to help your code. The bad news is that if you want to support arbitrary depths, it is far from a simple task(involves quite a bit of recursion). The other non-trivial task is to support path observer rebinding in the event of model list additions and subtractions.
A final note: Dustjs inheritance offers a superior way to reference your custom elements without relying on HTML Imports and ajax like Polymer.
You can do something like this:
{>my-element}
simply as a partial. And in my-element.html
<my-element>
<ui-template id="my-element-frag">...</ui-template>
</my-element>
this does require a second-step in your build process(grunt or gulp) that requires you to not only compile the external files but to parse your external files for your "template tags" and compile those as separate templates, which can then be referenced by, say, the id attribute(as the template name).

Related

What is the difference between lit-element & lit-html?

I have been learning Polymer and this came in - The future of web (lit-element & lit-html)
I understood that lit-html is for HTML templating with a couple of efficient techniques.
At the same time lit-element is a lightweight web component base class which has the lit-html inside it.
Question: If lit-element comes with lit-html, I would solely use the lit-element for all my purposes. What exactly does lit-html doing explicitly with its own separate context.
One should choose lit-element or lit-html while developing a standalone web application?
Any help on guiding through this would be of much help!
First, lets clarify the following points:
Web
Components
technologies are supported in modern browsers by default. You can build
a Web Component application using the browser's API.
HTML templates has been around since 2013 at least.
lit-element library is a "lightweight" version of Web Components. You'd use it if you want to build an application in Web Component and if you do so, you'd be using its built-in lit-html via html to create HTML templates
On the other hand, Just like you stated, lit-html is a library which has efficient mechanism to create and update HTML templates. You can use it for whenever you'd need an HTML template irrespective of the framework/library you are using for your website, if any.
For an example, you could build a website with jQuery or vanilla Web
Components and use lit-html to create the HTML templates.
lit-html is a library which deals with dom rendering like other libraries e.g. React
It uses the newest way of diffing the dom tree with help of native tagged templates.
var h1 = html`<h1>Header 1 <h1>`
like any other framework/library e.g. JSX it also provides you construct inside the tagged template and directives to help.
LitElement is a lightweight framework using lit-html as rendering engine. It provides you the observed properties, attributes and web components lifecycle callbacks
For a web application you should go with LitElement, if you do not want to reinvent the data binding, caching, callbacks etc. you would definitely require more like state tracking, routing etc. which you can employ from other libraries or develop your own.

How to declare OpenUI5 (SAPUI5) components in html and do data binding in html

It is simple to instance SAPUI5/OpenUI5 component as JavaScript variable and to assign its content to the div in html page. But is there some way how to declare SAPUI5/OpenUI5 component in the html file - actually - the best place where the instance of the component should belong? I have read about Angular.js and OpenUI5 integration but this effort was not continued. It is time consuming to write so much JavaScript code where the other frameworks use HTML tags.
First of all, you can write Views in XML, HTML, JSON and JavaScript. The corresponding Controller is always JavaScript.
Unlike angular.js, SAPUI5/OpenUI5 doesn't enhance the existing HTML but takes the Control definitions from the view and creates the DOM based on it (in the Control Renderers). Therefore the "language" of the view only changes the parsing function.
Based on the OpenUI5 Best Practices, the Explored App demoing the Controls, the Developer Guide (and my personal experience) SAP recommends using XML to create Views.
JavaScript Views might seem more powerful at first because you can include more logic in them. But that is also their biggest problem: By including logic in the View, you weaken the separation between View and Controller.
From my experience, declaring your Views in XML also makes them shorter (and more readable) compared to any other option.
Actually the best place is the JS code...google single page web applications. But if you really want to use html or xml you can create different types of SAPUI5 views the options are: Javascript XML HTML and JSON.
SAP recommends using the Javascript views/controllers they are more powerful.
The best way is to wrap the Angular js code as a OpenUI5 Component. You can use this Component any where in the openui5 application depending on the requirement.
This way the dependencies can be managed effectively and the code is modular. You can still have views and controllers within that.
........

Polymer and working with external JavaScript Libraries

With Shadow DOM, I can easily use external CSS frameworks like bootstrap nicely and it will only apply to my scope which is nice (example here).
However, this doesn't apply to JavaScript libraries as far as I know. If I, for example, need to work with jQuery on my web component, I basically make it available for entire page. What is the recommend way to work with external JavaScript libraries with Polymer? How should I handle cases where my web component (which is distributed through bower) needs one version of foo.js and the consumer needs another?
There is no JavaScript encapsulation solutions I know of.
Check if js encapsulation solutions exist, e.g. check zonejs and alternatives.
You may do it yourself but this will require you to devote some time to it. E.g. I've encapsulated Babel with with statement as shown here (not tested).

Dynamically created templates with Polymer in a Chrome app

I'm working on a Chrome app which needs to do two main things:
Automatically generate a UI from a list of fields and data types provided by an attached device.
Allow users to define and share their own presentation for the UI and automatically apply that presentation when the device is attached.
I'm using Polymer, and I figure the best way to achieve #2 is with user-provided Polymer elements. Then, I can simply bind the variables from the device to the UI, and the user's template can determine how to display and style them.
Achieving #1, then, is a matter of automatically generating a polymer element from an input schema. This is somewhat different from the usual approach, where I'd presumably define a repeated template with conditional child templates for each type of widget.
My questions, then, are:
How can I dynamically evaluate a polymer element/template from a remote source without violating the Chrome App's CSP, and without introducing significant XSS issues? (Hopefully, the former protects me from the latter?)
What's the easiest way to dynamially generate markup for a Polymer element? Can I define a meta-template and use the generated markup?
I am not entirely sure why you rule out using a pre-defined Polymer element with (admittedly, complicated) <template> logic in it, but if you're sure that you need things to be dynamic and generate the element's content on the fly while still making use of Polymer's data binding, then injectBoundHTML() might be what you're looking for.
It's unfortunately not documented at the moment, but there are examples of how to use it in the open issue tracking the documentation.
You can fetch the "bound" HTML from any source, and while I'm not an expert on CSP, I don't believe that it will trigger any additional CSP consideration.

Grabbing HTML from another page

I have two HTML files: One acts as a template, supplying the navigation, sidebars, etc., and the other has the main content. I'm trying to figure out how best to insert the content into the template. I need persistent URLs, so my plan was to have the content page essentially replace itself with the template, plugging the text back into the resulting page. I'm really new to front-end programming and I'm suspicious that this may be an anti-pattern, so my first question is about whether I'm barking up the right tree. The problem seems universal, and I'm sure there must be a best practice, though I haven't yet seen it discussed. If this is an acceptable way to proceed, then what JavaScript function would allow me to access the HTML of two different pages at the same time?
[EDIT: It's a small page on GitHub]
Do not do this. At current implementation HTML is not designed to be template engine. You can use HTML import but it has not full support in browsers. (compatibility table).
Usually this problem can be solved with:
Use frontend framework. Libraries like angular.js or polymer.js (and so on) usually has support of importing HTML documents in different forms.
Build your application HTML. Task runners like grunt.js usually has plugin that includes HTML.
Use server side technologies to extend your HTML from base layouts
If your application have to be consisted from different HTMLs I recommend you to try polymer. It is polyfill for web components and designed to work in such way by default.
UPD:
About edit to your question. It seems like you just need template engine for HTML. You can google for it. I use nunjucks - javascript port of python's template engine jinja2. It is lightweight, simple and can be compiled right in browser.
Another way is to use special tools for building static web pages. You have mentioned that your page is blog build from simple HTML pages. Try to use pelican. It is the static websites (blogs) generator. It is simple and fast. You can build your HTML even on your local machine and just push your HTML pages to github.

Categories