Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using parent component's template in Angular2

I want to inherit parent's template using component's inheritance in Angular.

Intro

I have some basic component (let's call it ParentComponent) and several childs of this component (Child1Component and Child2Component). I want to put default behavior in the ParentComponent and then just setup/extend this behavior in children components. ParentComponent template already contains all the needed things, so I want children components to use this template by default.


First variant of implementation (does not work, Error: No template specified for component Child1Component):

@Component({
    selector: 'app-parent',
    templateUrl: './app-parent.component.html',
    styleUrls: ['./app-parent.component.scss']
})
export class ParentComponent {
}

@Component({
    selector: 'app-child1'
})
export class Child1Component extends ParentComponent {
}


@Component({
    selector: 'app-child2'
})
export class Child2Component extends ParentComponent {
}

I found that I can set templateUrl and styleUrls of children to parent's template, but it will work only if ViewEncapsulation of children is set to None.

Second variant (it works, but I don't like it):

@Component({
    selector: 'app-parent',
    templateUrl: './app-parent.component.html',
    styleUrls: ['./app-parent.component.scss']
})
export class ParentComponent {
}

@Component({
    selector: 'app-child1',
    templateUrl: '../parent/app-parent.component.html',
    styleUrls: ['../parent/app-parent.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class Child1Component extends ParentComponent {
}

@Component({
    selector: 'app-child2',
    templateUrl: '../parent/app-parent.component.html',
    styleUrls: ['../parent/app-parent.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class Child2Component extends ParentComponent {
}

I don't like this solution cause of

  1. No view encapsulation in child components;
  2. Template and style urls copy-paste for every child component.

Can you please suggest me better solution for this task?

like image 310
Ivan Kalita Avatar asked Nov 03 '17 10:11

Ivan Kalita


People also ask

How do you communicate between parent and child components?

@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.

How do you pass data from parent component to child component?

To let Angular know that a property in a child component or directive can receive its value from its parent component we must use the @Input() decorator in the said child. The @Input() decorator allows data to be input into the child component from a parent component.


1 Answers

Second approach is the only possible way, because there are rules for decorator inheritance, see https://github.com/angular/angular/issues/11606.

@Component decorator can not be partially inherited, it is all or nothing.

like image 178
kemsky Avatar answered Oct 04 '22 21:10

kemsky