How to initialize a web component from Javascript?

Let's say I have the following web component:

<link rel="import" href="my-dialog.htm"> <my-dialog id='mydialog1' heading="A Dialog">Lorem ipsum</my-dialog> 

See here for more information: http://cbateman.com/blog/a-no-nonsense-guide-to-web-components-part-1-the-specs/

and here: http://www.revillweb.com/tutorials/web-component-tutorial/

However, in addition to attributes, sometimes I would like to initialize it with some object that has a bunch of properties, for example:

 var obj = { heading: 'hello there', data1: 123, name: 'blabla' }; //^^ this can be any type of data.. think some kind of data model here, and maybe I get this model from the server. 

Therefore, I cannot send the specified object to my html via attributes, because I can have many settings and / or I can get it at a later point from the server, so I need to do this in javascript.

So, what I was doing, I just took an object after creating it:

 // initialize is a function I have inside my web component $('#mydialog1').get(0).initialize(obj); 

^^ And this works, initialize (..) is a function inside my web component .. But:

Question # 1 I wonder if this is the right way to initialize the web component as it seems a bit messy.

Also, if there is one instance of the web component in the code:

 $('body').append("<my-dialog id='bla'></my-dialog>"); $('#bla').get(0).initialize(obj); 

Question # 2 Can I assume on the second line that 'bla' was created here with all its methods? (pretty funny, it works, but I thought it might be better to wait for some event or something that the component is ready)

+6
source share
5 answers

Since append has synchronous (opposite to asynchronous) behavior, it will always work.

Do not mutate your code base with unnecessary security networks (events, polling ...).

In short, immediately after executing the .append element, it is present in the DOM, and you can request it using the selectors and do whatever you want to do with it.

+4
source

Like almost all JavaScript methods, adding HTML is synchronous, which means that you can expect the right DOM elements to be created when the function returns - if not, the function will receive callbacks or return a promise or the like. Thus, you can believe that the thing was created and initialized. And initializing it this way is probably the best way to do it (although there might be a way to do it all on one line.)

If you feel the need to convince yourself that this import method (anything related to an external file) is synchronous and not asynchronous, you can do the following on a * nix system:

  • Create one named pipe and yes pipe for it. ( $ yes >pipe1 )
  • Create the appropriate HTML (or JS or whatever) header that will output yes (an endless series of y followed by a line) will syntactically correct your situation.
  • Create another named pipe and write a title followed by the first named pipe (using cat ). ( $ cat header.htm pipe1 >pipe2.htm )
  • Run the import method using the name of the second named pipe. ( <link rel="import" href="pipe2.htm"> or var x = require("pipe2.js") )

Is your user interface compatible? If so, then it is synchronous. Does he keep going? Then it is asynchronous.

+1
source

Why are you setting attributes through an object? I would make the settings and then pass them as follows:

 document.getElementById("someID").style.width = widthVar; document.getElementById("someID").name = nameVar; document.getElementById("someID").style.color = colorVar; 
0
source

Instead of creating it in html:

 $('body').append("<my-dialog id='bla'></my-dialog>"); $('#bla').get(0).initialize(obj); 

You can also do something like:

 var myDialog = document.createElement('my-dialog'); myDialog.initialize(obj); $('body').append(myDialog); 
0
source

Web components are designed to interact with their attributes so that they can remain truly compatible.

If you get your data after you have added the component to the DOM, you can still interact with the web component using the following attributes:

Say you have already added the dialog component added to the DOM:

 <my-dialog id='mydialog1' heading="A Dialog">Lorem ipsum</my-dialog> 

So, you can easily update these attributes of DOM elements with JavaScript later on:

 document.querySelector('#mydialog1').setAttribute('init-data', JSON.stringify(obj)); 

And then in the web component, you can respond to attribute changes as follows:

 //Called when one of this components attributes change proto.attributeChangedCallback = function(attrName, oldVal, newVal) { switch (attrName) { case "init-data": //DO SOMETHING WITH newVal var dataObj = JSON.parse(newVal); break; } }; 

That should give you everything you need. I would seriously recommend writing your web components with ES2015, the code is much cleaner, see this lesson: http://www.revillweb.com/tutorials/web-components-with-es2015-es6/

Hope this helps!

0
source

All Articles