2
votes

I have multiple nested web components to represent a grid. I need to compose these in dart code. I have a function to create the web component as recommended by the dart docs :

void addWebComponent(WebComponent component,String tagName,WebComponent parent) { 
    component.host = (new Element.html("<${tagName}></${tagName}>"));        
    var lifecycleCaller = new ComponentItem(component)
    ..create();
    parent.append(component.host);
    lifecycleCaller.insert();
    return;
}

Each web component contains a template like so :

  <template>
      <div class="grid">
         <div class="large-12 columns" >                    
            <content></content>
         </div>
       </div>          
  </template>

My assumption is that calling parent.append(component.host); will add the injected web component html into the CONTENT element. It doesn't. This is what I'm expecting as a result :

<x-grid>
      <div class="grid">
         <div class="large-12 columns">
             <x-row> 
                  <div class="row">...</div>           
             </x-row>
         </div>
       </div>          
</x-grid>

This is what I get :

 <x-grid>
      <div class="grid">
         <div class="large-12 columns"> 
                 **[Content should be here!]**               
         </div>
       </div>    
         **[ CONTENT ENDS UP HERE]**
         <x-row> 
                  <div class="row">...</div>           
             </x-row>

</x-grid>

My guess is that from dart code you can't add to the web component's content via parent.append(component.host). Is there some other function or steps required to make this work? It's killing me.

1
What's being passed as "String tagName"? Additionally is 'parent' already inserted into the DOM before the addComponent function is called?Matt B
the tagNames are "x-grid" when called from main,"x-row" when called from gridComponent,"x-column" when called from RowComponent.logan
I'll have to test more to see if the parent is inserted into the DOM before addComponent is called. I'm under the impression that lifecycleCaller.insert() adds the component to the Dom. If that's the case then no the parent is not added to the dom until after the component is added to the parent. The docs are weak concerning dynamically creating web components.logan
Your "host" should be the HtmlElement that your element extends (ie. DivElement). Your 'component' should be the WebComponent subclass you created for it (ie: new XRow();). I tried similar test case but couldn't reproduce your results, my elements were nested as you expected. But I had a much smaller example than I'm sure your code is and probably have some significant differences.Matt B
I changed the host to be a plain Div but I get the same result. None of the nested components are inserted into the content area. This is also the case for nesting components in html : <x-grid><x-row></x-row></x-grid> The damn x-row is appended as the last child of the parent component instead of being inserted into <content></content> area of the template.logan

1 Answers

2
votes

Try this:

Add to parent:

List<WebComponent> items = toObservable([]);

Change:

parent.append(component.host);

To:

parent.items.add(component);

Then modify the HTML to be like:

<template>
  <div class="grid">
     <div class="large-12 columns" template iterate="item in items">                    
        {{ new SafeHtml.unsafe(item.host.innerHtml) }}
     </div>
  </div>          
</template>