How to add a component programmatically in Angular.Dart?

angular-dart, dart, shadow-dom

Solution

This would be a proper use of the block API.

class AppComponent extends NgShadowRootAware {
  Compiler compiler;
  Injector injector;
  Scope scope;
  DirectiveMap directives;

  AppComponent(this.compiler, this.injector, this.scope, this.directives);

  void onShadowRoot(ShadowRoot shadowRoot) {
    DivElement inner = shadowRoot.querySelector("#inner");
    inner.appendHtml("<inner-comp></inner-comp>");    
    BlockFactory template = compiler([inner], directives);
    Scope childScope = scope.$new();
    Injector childInjector = 
        injector.createChild(new Module()..value(Scope, childScope));
    template(childInjector, [inner]);
  }
}

Also, if you ever need to recompile the inner template make sure you do `childScope.$destroy()` on the previous `childScope`.

Problem

I would like to dynamically build a component tree basing on some information received from AJAX calls. How to programmatically add a component to the DOM from inside of other component? I have `<outer-comp>` and I would like, basing on some logic, insert an `<inner-comp>`. The following code just inserts the elements `<inner-comp></inner-comp>` to the DOM, and not actual `<inner-comp>` representation. ``` @NgComponent( selector: 'outer-comp', templateUrl: 'view/outer_component.html', cssUrl: 'view/outer_component.css', publishAs: 'outer' ) class AppComponent extends NgShadowRootAware { void onShadowRoot(ShadowRoot shadowRoot) { DivElement inner = shadowRoot.querySelector("#inner"); inner.appendHtml("<inner-comp></inner-comp>"); } } ``` Update: I managed to render the inner component correctly in the following way, but I'm still not sure if this is the proper way: ``` class AppComponent extends NgShadowRootAware { Compiler compiler; Injector injector; AppComponent(this.compiler, this.injector); void onShadowRoot(ShadowRoot shadowRoot) { DivElement inner = shadowRoot.querySelector("#inner"); inner.appendHtml("<inner-comp></inner-comp>"); BlockFactory template = compiler(inner.nodes); var block = template(injector); inner.replaceWith(block.elements[0]); } ``` }

Original source