¿Cómo agregar un componente mediante progtwigción en Angular.Dart?

Me gustaría construir dinámicamente un árbol de componentes basándose en cierta información recibida de las llamadas AJAX.

¿Cómo agregar un componente programáticamente al DOM desde el interior de otro componente? Tengo y me gustaría, basándome en cierta lógica, insertar un . El siguiente código simplemente inserta los elementos en la representación DOM, y no en la real .

 @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(""); } } 

Actualización: Pude renderizar correctamente el componente interno de la siguiente manera, pero todavía no estoy seguro de si esta es la manera correcta:

 class AppComponent extends NgShadowRootAware { Compiler compiler; Injector injector; AppComponent(this.compiler, this.injector); void onShadowRoot(ShadowRoot shadowRoot) { DivElement inner = shadowRoot.querySelector("#inner"); inner.appendHtml(""); BlockFactory template = compiler(inner.nodes); var block = template(injector); inner.replaceWith(block.elements[0]); } 

}

    Este sería un uso adecuado de la API de bloque.

     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(""); BlockFactory template = compiler([inner], directives); Scope childScope = scope.$new(); Injector childInjector = injector.createChild(new Module()..value(Scope, childScope)); template(childInjector, [inner]); } } 

    Además, si alguna vez necesita recomstackr la plantilla interna, asegúrese de hacer childScope.$destroy() en el childScope anterior.

    La API ha cambiado en AngularDart 0.9.9:

    • BlockFactory ahora es ViewFactory
    • scope. $ new ahora parece ser scope.createChild (scope.context)
    • injector.createChild (modules) ahora requiere una lista de módulos (en lugar de uno solo)

    AngularDart 0.10.0 presenta estos cambios:

    • NgShadowRootAware no es ShadowRootAware
    • ..value () ahora es ..bind (., toValue:.)

    Entonces el código de pavelgj ahora se ve así:

     class AppComponent extends ShadowRootAware { 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(""); ViewFactory template = compiler([inner], directives); Scope childScope = scope.createChild(scope.context); Injector childInjector = injector.createChild([new Module()..bind(Scope, toValue: childScope)]); template(childInjector, [inner]); } } 

    El código anterior muestra un trabajo más prolongado debido a cambios en la biblioteca Angular Dart. Específicamente ViewFactory.call que ya no toma un inyector pero toma un Scope y un DirectiveInjector. Intenté adaptar lo que está arriba y me acerqué mucho. El componente aparece pero ninguno de los enlaces se reemplaza (veo {{cmp.value}} por ejemplo.

    Aquí está el código que estoy usando. Creo que el problema aquí es que DirectInjector entrará como nulo.

     void main() { IBMModule module = new IBMModule(); AngularModule angularModule = new AngularModule(); Injector injector = applicationFactory() .addModule(module) .run(); AppComponent appComponent = injector.get(AppComponent); appComponent.addElement(""); } @Injectable() class AppComponent { NodeValidator validator; Compiler _compiler; DirectiveInjector _injector; DirectiveMap _directiveMap; NodeTreeSanitizer _nodeTreeSanitizer; Scope _scope; AppComponent(this._injector, this._compiler, this._directiveMap, this._scope, this._nodeTreeSanitizer) { validator = new NodeValidatorBuilder.common() ..allowCustomElement("BRAZOS-INPUT-STRING") ..allowHtml5() ..allowTemplating(); } void addElement(String elementHTML) { DivElement container = querySelector("#container"); DivElement inner = new DivElement(); inner.setInnerHtml(elementHTML, validator: validator); ViewFactory viewFactory = _compiler.call([inner], _directiveMap); Scope childScope = _scope.createChild(new PrototypeMap(_scope.context)); if (_injector == null) { print("injector is null"); } View newView = viewFactory.call(childScope, _injector); container.append(inner); newView.nodes.forEach((node) => inner.append(node)); } } class IBMModule extends Module { IBMModule() { bind(BrazosInputStringComponent); bind(BrazosTextAreaComponent); bind(BrazosButtonComponent); bind(ProcessDataProvider, toImplementation: ActivitiDataProvider); bind(AppComponent); } } 

    Finalmente hice que esto funcionara pero no estaba contento con tener que agregar un temporizador:

     @Injectable() class AppComponent{ NodeValidator validator; Compiler _compiler; DirectiveInjector _directiveInjector; DirectiveMap _directiveMap; NodeTreeSanitizer _nodeTreeSanitizer; Injector _appInjector; Scope _scope; AppComponent(this._directiveInjector, this._compiler, this._directiveMap, this._nodeTreeSanitizer, this._appInjector, this._scope) { validator = new MyValidator(); } void addElement(String id, String elementHTML) { DivElement container = querySelector(id); DivElement inner = new DivElement(); container.append(inner); Element element = new Element.html(elementHTML, validator: validator); ViewFactory viewFactory = _compiler.call([element], _directiveMap); if (_scope != null) { Scope childScope = _scope.createProtoChild(); View newView = viewFactory.call(childScope, _directiveInjector); newView.nodes.forEach((node) => inner.append(node)); Timer.run(() => childScope.apply()); } else { print("scope is null"); } } } 

    EDITAR

    El paquete http://pub.dartlang.org/packages/bwu_angular contiene este decorador / directiva como bwu-safe-html

    ——

    Yo uso una directiva personalizada para eso

     @NgDirective( selector: '[my-bind-html]' ) class MyBindHtmlDirective { static dom.NodeValidator validator; dom.Element _element; Compiler _compiler; Injector _injector; DirectiveMap _directiveMap; MyBindHtmlDirective(this._element, this._injector, this._compiler, this._directiveMap) { validator = new dom.NodeValidatorBuilder.common() ..allowHtml5() ..allowImages(); } @NgOneWay('my-bind-html') set value(value) { if(value == null) { _element.nodes.clear(); return; } _element.setInnerHtml((value == null ? '' : value.toString()), validator: validator); if(value != null) { _compiler(_element.childNodes, _directiveMap)(_injector, _element.childNodes); } } } 

    Se puede usar como

     my-bind-html='ctrl.somehtml' 

    Problema angular
    Creé un problema para incluir esta funcionalidad en Angulares ng-bind-html https://github.com/angular/angular.dart/issues/742 (rechazado)