最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - How to Initialize a Web Component From Javascript? - Stack Overflow

programmeradmin4浏览0评论

Let's say I have the following web-ponent:

<link rel="import" href="my-dialog.htm">

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

See here for more info: /

and here: /

However, apart from attributes sometimes I'd 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.

So I can't send the above object within my html via attributes, cause I might have alot of settings and/or I might get it at a later point from the server, so I need to do it in javascript.

So what I've been doing is I've just been taking the object after it has been created:

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

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

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

Also, if one instantiates a web-ponent in 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' has been created here with all its methods? (funny enough, this works but I thought maybe it'd be better to wait for some kind of event or something that the ponent is ready)

Let's say I have the following web-ponent:

<link rel="import" href="my-dialog.htm">

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

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

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

However, apart from attributes sometimes I'd 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.

So I can't send the above object within my html via attributes, cause I might have alot of settings and/or I might get it at a later point from the server, so I need to do it in javascript.

So what I've been doing is I've just been taking the object after it has been created:

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

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

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

Also, if one instantiates a web-ponent in 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' has been created here with all its methods? (funny enough, this works but I thought maybe it'd be better to wait for some kind of event or something that the ponent is ready)

Share Improve this question edited Jan 4, 2016 at 16:01 Shai UI asked Dec 30, 2015 at 20:26 Shai UIShai UI 52k77 gold badges218 silver badges316 bronze badges 10
  • 2 What technology is this? What page might we be referred to to learn a little more about it? And what question do you have specifically that isn't answered by that page? – TheHans255 Commented Dec 30, 2015 at 20:29
  • this is web ponents – Shai UI Commented Dec 30, 2015 at 20:29
  • 1 As in developer.mozilla/en-US/docs/Web/Web_Components ? OK, then. Are you asking how to reliably bind data to a Web Component without running the risk of doing so before it is instantiated? – TheHans255 Commented Dec 30, 2015 at 20:32
  • yes. and if I'm passing the data correctly through code or if there is a better way. – Shai UI Commented Dec 30, 2015 at 20:34
  • Wouldn't you do stuff like that in the "created" callback? Or maybe the "attached" callback? – Pointy Commented Dec 30, 2015 at 20:34
 |  Show 5 more ments

5 Answers 5

Reset to default 1

Because append has a synchronous(opposite of async) behavior, it will always work.

Do not litter your codebase with needless safety nets(events, polling...).

In short, right after .append is executed the element is present on DOM and you can query it with selectors and do whatever you want to do with it.

Like virtually all JavaScript methods, HTML appending is synchronous, which means that you can expect the correct DOM elements to be constructed when the function returns - if not so, the function would accept callbacks or return a Promise or similar. Thus, you can trust that the thing has been created and initialize it. And initializing it in this way is probably the best thing to do (though there might be a way to do it all in one line.)

If you feel the need to convince yourself that a given import method (anything that consults an external file) is synchronous rather than asynchronous, you can do the following on a *nix system:

  1. Create one named pipe and pipe yes to it. ($ yes >pipe1)
  2. Create an appropriate HTML (or JS or whatever) header that would make the output of yes (an infinite series of ys followed by linefeeds) syntactically correct for your situation.
  3. Create another named pipe and pipe the header followed by the first named pipe (using cat) to it. ($ cat header.htm pipe1 >pipe2.htm)
  4. Run your import method using the name of the second named pipe. (<link rel="import" href="pipe2.htm"> or var x = require("pipe2.js"))

Does your UI hang? If so, then it's synchronous. Does it keep on going? Then it's asynchronous.

Why are you setting the attributes via an object? I'd make settings and then pass them this way:

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

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);

Web ponents are designed to be interacted with via their attributes, this way they can stay truly interoperable.

If you get your data after you have added the ponent to the DOM you can still interact with the web ponent via attributes like this:

Let's say you have your dialog ponent already added to the DOM:

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

So you can easily update this DOM elements attributes at a later time with JavaScript:

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

And then within the web ponent you can react to attribute changes as follows:

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

This should give you everything you need. I'd seriously remend writing your web ponents with ES2015 the code is a lot cleaner, see this tutorial: http://www.revillweb./tutorials/web-ponents-with-es2015-es6/

Hope this helps!

发布评论

评论列表(0)

  1. 暂无评论