How to Extend/Inherit Angular2 Component?

Asked

Viewed 2,209 times

8

Doubt

I would like to create extensions for some components already implemented in Angular 2, without having to rewrite them almost completely, because the base component could undergo changes and I would like these changes to be reflected also in their derivative components.

Example

I created this simple example to try to expose my doubt better:

With the following base component app/base-panel.component.ts:

import {Component, Input} from 'angular2/core';

@Component({
    selector: 'base-panel',
    template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
    styles: [`
    .panel{
    padding: 50px;
  }
  `]
})
export class BasePanelComponent { 
  
  @Input() content: string;
  
  color: string = "red";
  
  onClick(event){
    console.log("Click color: " + this.color);
  }
}

I would like to create another derivative component that would only change, for example, the behavior of the base component, in the case of the color example, app/my-panel.component.ts:

import {Component} from 'angular2/core';
import {BasePanelComponent} from './base-panel.component'

@Component({
    selector: 'my-panel',
    template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
    styles: [`
    .panel{
    padding: 50px;
  }
  `]
})
export class MyPanelComponent extends BasePanelComponent{
  
  constructor(){
    this.color = "blue";
  }
}

Full and functional example in Plunker.

Note: Obviously this example is simple and could be solved otherwise without needing to use inheritance, but it aims only to illustrate the real problem.

Problem

As you can see in the implementation of the derivative component app/my-panel.component.ts, much of the implementation was repeated, and the only part actually inherited was the class BasePanelComponent, but the @Component had to be basically repeated completely, and not only the parts changed, as o selector: 'my-panel'.

Question

The some way to make a literally complete inheritance of an Angular2 component, inheriting the definitions of class and marking/annotations, such as @Component?

Edit 1 - Resource Request

Feature request added to angular2 project on Github: Extend/Inherit angular2 Components Annotations #7968

Edit 2 - Closed Request

The request was closed, for this reason, that briefly would be not knowing how will be made the merge of Developer. Leaving us no options. So my opinion is is quoted in Issue, that in Portuguese would be something like:

"If Decorator/Annotation has these limitations, which according to your arguments can not be easily circumvented in the library, I ask you a question: Why do you use them? Wouldn’t it be a better option to ignore/discard them for development a library of angular2 size and complexity? Or want to invest time/money in a library with primary limitations like the one listed on this Issue? I believe that this is still the time for major changes that can alter the direction of angular2, because the library is still in RC1. It would be extremely disappointing to see a stable version of a library as angular2 being released with such a limitation.".

  • If I understood your doubt correctly you’d like to have one Component Child (may have more than one Component Child within the same Component Parent), let’s say, that you manage to change some property of your Component Parent (1 Component Parent for many ComponentChild). Would that be?

  • @Celsomtrindade, is if I understood your question I think it’s almost that! Briefly, I would like the real inheritance effect for the components!

2 answers

1

it does not make much sense to inherit the class of components, if I understand well what you want to do is reuse components, if that is simple to do, just imagine that you are in HTML and make a bind in the property that was created in the parent Component, see this class of Loiane Groiner she explains exactly that: https://www.youtube.com/watch?v=UbSmzblc-qY

I hope I’ve helped.

A Hug.

  • It makes a lot of sense to inherit a component, whether you have a component of your own or primarily a third party, that you want to create others with just a few feature changes. As for example, you have a third component of bar graph and this does not espoe a data refresh method, only providing internally. Then you can inherit this component and expose this method for external use. This is just a simple example, but in my real cases there are other more complex applications.

  • So, my dear I understand your point of view but an inheritance is a specialization of a parent class, ie she is the most specialized parent class so much that it is possible to morph from one to the other, on the other hand the template does not suffer inheritance, so the same should be +/-repeated in inheritance or compound when using reuse/composition of other components, so I said that it does not make much sense to inherit but to reuse making composition. on the other hand you can use the HTML template file so you won’t need to rewrite the template.

  • Correct, this is true for some cases, but if you are using third party components, not always the component has been developed enabling composition, often what you want to change is not exposed through composition and inheritance is the only alternative (or else a copy/Paste, which would be a very bad thing because it would make it difficult for you to maintain compatibility with later versions of the component). And the case of HTML template file for third party components you do not have access to reference these files and sometimes third party components or use this mechanism.

0

It’s like you have an abstract class that would be this base class. It doesn’t necessarily have to be a component, but it can implement lifecycles like init and such. Within it you can have common behaviors that you would like to replicate in the child classes as well as additional specific behaviors. However you can not extend the annotationtion Component. In addition you can use the same css if you import from the same file but the html is ideal each have their own.

follows a diagram more or less of how it would be:

                             UsersListBaseComponent
                             /                    \
                            /                      \
                UsersListMobileComponent        UsersListDesktpComponent

Classes:

export abstract class UsersListBaseComponent implements onInit { 

  @Input() content: string; //funciona

  userList$: Observable<User[]>;

  constructor(private userService:UserService){ // vc consegue ter depedencias
 }

 ngOnInit(){
    this.userList$ = this.userService.pegarUsers(); // vc consegue setar atributos
 }

  funcaoComum(event){
  //essa funcao fica disponivel para as classes que herdarem;
  }
}

Daughter class

export abstract class UsersListMobileComponent implements onInit { 

  constructor(private userService:UserService, private bananaService:BananaService){ // vc consegue ter depedencias extras
    super(userService)//passar Depedencias
  }

 ngOnInit(){
    super.ngOnInit();
 }

  funcaoEspecifica(event){
  //essa funcao fica disponivel somente para a classe filha
  }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.