0

dart 1.24.3, Angular 4.0.0

For reusable reasons, I have divided my application into many packages. Let's say that I'm using package C, that depends on package B that depends on package A. A is used also in other packages, and B can be used stand-alone. Finally, C add some more info to B and it is in some way customized.

Now, in package A I have a modal window that shows some info, but in package B I should add a component and in package C even one more. As this modal window is used in all my component forms, I cannot customize it inside the child packages, because this would mean to inherit all parent forms and customize them. What I would like to use is something like the providers injection (example what I would like to declare in my application component in Package C):

 ModalWindowComponent,
      const Provider(pack_b.ModalWindowComponent, useClass: ModalWindowComponent),
      const Provider(pack_a.ModalWindowComponent, useClass: ModalWindowComponent)

Googling I have seen something that maybe I can use in my case, the ComponentResolver class. But I could not get if it is something new to Angular 5 or can be used also in angular 4. In some other places it seems also that it will be deprecated, so I'm a little bit confused. More, I do not need to dynamically add a component in the DOM, but dynamically substitute the component with the one (that inherits the base one) from the child package.

Is there a way to do that? Is there some example that I can give a look at?

Ali Akbarpour
  • 958
  • 2
  • 18
  • 35
J F
  • 1,058
  • 2
  • 10
  • 21
  • I just added an updated example to https://stackoverflow.com/questions/36325212/angular-2-dynamic-tabs-with-user-click-chosen-components/36325468#36325468 You can't inject components, but you can pass component types around and then make Angular instantiate them where you need them and add them to the view using `ViewContainerRef`- – Günter Zöchbauer Feb 26 '18 at 17:38
  • Sorry Günter, is it the right example? It is not a Dart project and I could not find any reference to NgComponentOutlet – J F Feb 26 '18 at 18:05
  • Sorry, I missed that the question is about Dart. The basic approach should work the same. https://github.com/dart-lang/angular/blob/master/doc/component_loading.md provides some datails – Günter Zöchbauer Feb 26 '18 at 18:08
  • I do not know TypeScript and even if the syntax is similar, sometimes there are some differences that I do not know how to port to Dart. But, anyway, thanks, I will try to understand that example. I thought it was an NgComponentOutlet example. – J F Feb 26 '18 at 18:20
  • What is not clear to me is how I can get the right compoennt in the class of the A package. I means, In your example all components are known and from the same package. But in my use-case, the class that have to load dynamically the component does not know the component that will be injected because it comes from a child package. – J F Feb 26 '18 at 18:23
  • Where you import the class from determines what component will be created – Günter Zöchbauer Feb 26 '18 at 18:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165855/discussion-between-j-f-and-gunter-zochbauer). – J F Feb 26 '18 at 18:30

1 Answers1

8

You can use ComponentLoader which requires passing the ComponentFactory and a place in the DOM. There are good examples in methods' documentation.

You get the ComponentFactory for the Component by importing the .template.dart file which has @Component annotation, and appending NgFactory to the name of the component, for example:

file foo.dart:

@Component(selector: 'foo')
class FooComponent {}

file bar.dart:

import 'foo.template.dart';

@Component(selector: 'bar', template: '<div #placeholder></div>')
class BarComponent {
  final ComponentLoader _loader;

  @ViewChild('placeholder', read: ViewContainerRef)
  ViewContainerRef theDiv;

  BarComponent(this._loader);

  void load() {
    _loader.loadNextToLocation(FooComponentNgFactory, theDiv);
  }
}
rkj
  • 8,787
  • 2
  • 29
  • 35
  • 1
    Thanks, now it works. As I have to inherit the component from a sub-package I had to create a service that returned the component factory and then inject the service. The problem now is that following the approach you outlined, (as in the guidelines that I have found), it is suggested to use the component factory generated in the template. But this in my IDE causes the environment to show an error (the template has not been generated yet). I made the example work also with a ComponentResolver instance, but it is discouraged. How can I generate the componentFactory without the IDE alerts? – J F Feb 27 '18 at 13:23
  • I guess this depends heavily on environment and IDE. If you build your project so that the generated files are actually on disk you should be able to configure the IDE to see them (it's in Modules in IntelliJ). It is a general problem with generated files in Dart and definitely can be improved... – rkj Feb 28 '18 at 05:09