Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to create an angular dart component dynamically. I know it's not a best practice but I have to because of how my angular widgets are being inserted.

I based my work off of:

How to add a component programatically in Angular.Dart?

The code samples on longer work because of changes in the Angular Dart library.

I got this code to work but it's inconsistent. The solution was the Timer.run() to fire the scope.apply. The problem with that is:

  1. It stinks to make a call like that and would perform terribly with lots of components
  2. It seems to work randomly. Most of the time it does but occasionally it doesn't do the {{foo}} replacements
void main() {
  IBMModule module = new IBMModule();
  AngularModule angularModule = new AngularModule();

  Injector injector = applicationFactory()
  .addModule(module)
  .run();

  AppComponent appComponent = injector.get(AppComponent);
  appComponent.addElement("<brazos-input-string label='test'/>");
}

class MyValidator implements NodeValidator {


  bool allowsElement(Element element) {
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return true;
  }

}

@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 elementHTML) {
    DivElement container = querySelector("#container");
    DivElement inner = new DivElement();
    container.append(inner);
    Element element = new Element.html(elementHTML, validator: validator);
    // inner.setInnerHtml(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");
    }
  }
}


class IBMModule extends Module {
  IBMModule() {
    bind(BrazosInputStringComponent);
    bind(BrazosTextAreaComponent);
    bind(BrazosButtonComponent);
    bind(ProcessDataProvider, toImplementation: ActivitiDataProvider);
    bind(AppComponent);
  }
}
share|improve this question
    
You should be able to omit .call in _compiler.call(. Methods named call can be invoked like a function (the same with viewVactory.call( (that doesn't change anything with your problem at hand though) –  Günter Zöchbauer Oct 12 '14 at 13:03
    
Is injecting the scope as constructor argument still the right way to do it? (I don't use Angular since a while) As far as I remember I read about implementing ScopeAware to get the scope. Have you tried to get the scope passid in this way? –  Günter Zöchbauer Oct 12 '14 at 13:05
    
Gunter, I was using call just to clarify the code. I'll try ScopeAware. Do I need to call scope.apply()? Is that the missing link here to getting these variables evaluated? –  user1637302 Oct 13 '14 at 13:11
    
I don't think so. If you read the CHANGLOG at pub.dartlang.org/packages/angular you'll see that using a constructor argument to get the scope is invalid in 1.0. I guess you just get an invalid scope (but I'm a bit out of practice in Angular.dart and don't know for sure). –  Günter Zöchbauer Oct 13 '14 at 13:14
    
That's odd because NgInclude (which I patterned this off of at first) still takes in Scope as a constructor argument. –  user1637302 Oct 13 '14 at 13:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.