-1

Structure of classes is:

/* Common class */

interface Tree {
}

class TreeBase {
   // Commmon methods for all successors
}

Concrete classes:

interface TreeLayersActions { do(): void; }
interface TreeMapActions { make(): void; }

TreeLayers extends TreeBase implements TreeMapActions {
}

TreeMap extends TreeBase implements TreeLayersActions{
}

So, I try to inject concrete implementation to component:

export class TreeComponent implements OnInit, OnDestroy, TreeLayersActions, TreeMapActions {
   constructor(private tree: TreeBase) {

   }

         make(): void {
          this.tree.getNodeStyles(node); // Here problem
       }
       do(): void {}
}

Problem is that getNodeStyles is not presented in private tree: TreeBase. Because it is concrete implementation.

I have tried this:

constructor(private tree: TreeLayers | TreeMap) {
}

Component should work with different service implementations to deligate execution to service.

I have decided to create a service that create a specific tree instance and implements all interfaces from all concrete classes:

class TreeService implements TreeLayerActions, TreeMapActions {
  public tree: TreeLayers | TreeSearch;

  constructor(type: string) {
      switch (type) {
      case "layers":
        this.tree = new TreeLayers(null);
        break;
      case "map":
        this.tree = new TreeSearch(null);
    }
 }

 /* Realization interfaces TreeLayerActions and TreeMapActions that deligates calls to service
 changeTileLayer(treeNode: TreeNode): void {
    this.tree.changeTileLayer(treeNode: TreeNode);
 }
 // Other methods
}

So, then in component I can inject the service TreeService and implement also TreeLayerActions, TreeMapActions, Tree interfaces, that deligates calls to service.

I think it is dirty solution, because I pollute the component by all methods from each implementations.

1 Answers1

0

In the module you can 'provide' another class to use:

providers:[{ provide: Tree, useClass: AnotherTree }]
Alexander
  • 3,019
  • 1
  • 20
  • 24
  • Sure, but I can not inject interface `Tree` –  Feb 02 '21 at 13:18
  • And class ` AnotherTree` has own methods that not presented in `Tree`. The Tree contains only common methods for all classes. How to know inside component what is AnotherTree or another class? –  Feb 02 '21 at 13:21
  • So, I can do this: `constructor(private tree: TreeA | TreeB | TreeC | TreeD) {}` the component should no about concrete realization. –  Feb 02 '21 at 13:23
  • But from another side if I dont know about concrete service injected I dont know which methos it provides for component despite common methods from Tree –  Feb 02 '21 at 13:31
  • Create an abstract class Tree and let TreeABCD extend it. Then you have constructor (private tree:Tree) and in your subclass you pass TreeA to super() – Alexander Feb 02 '21 at 13:50
  • Could you check my question, I have updated –  Feb 02 '21 at 13:57
  • It is not possibel to create instrance of abstract class –  Feb 02 '21 at 13:58
  • I have also tried this: `constructor(private tree: TreeLayers | TreeSearch) {}` –  Feb 02 '21 at 14:19