Reputation: 331
I built a header row component for table-styled data in a report that allows multi-column sorting. It's pretty simple: one property, two functions and an @Output() to let the parent component know when the order has changed.
I'd like to use now use that component in all of the other reports I have - every one will have the same logic, but they'll each have a different display.
I know than I can add an @Input() for reportType and then *ngSwitch code in my template, but I'd love to find a way to actually isolate the HTML for each header into it's own file (possibly with it's own SCSS file too) without creating a bunch of components with exactly the same logic.
That logic is included below just for fun.
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'sort-row',
templateUrl: './sort-row.component.html',
styleUrls: ['./sort-row.component.scss']
})
export class SortRowComponent {
sortOrder: string[] = [];
@Output() sortChanged: EventEmitter<string[]> = new EventEmitter<string[]>();
constructor() {}
sortingBy(field, dir?) {
if (dir) {
if (dir === 'desc') {
field = '-' + field;
}
return this.sortOrder.indexOf(field) !== -1;
} else {
return this.sortOrder.indexOf(field) !== -1 || this.sortOrder.indexOf('-' + field) !== -1;
}
}
toggleSortCol(col, evt) {
const ascIdx = this.sortOrder.indexOf(col);
const descIdx = this.sortOrder.indexOf('-' + col);
if (!evt.shiftKey) {
if (ascIdx !== -1) {
this.sortOrder = ['-' + col];
} else if (descIdx !== -1) {
this.sortOrder = [col.replace('-', '')];
} else {
this.sortOrder = [col];
}
} else {
if (ascIdx !== -1) {
this.sortOrder[ascIdx] = '-' + col;
} else if (descIdx !== -1) {
this.sortOrder[descIdx] = col.replace('-', '');
} else {
this.sortOrder.push(col);
}
}
this.sortChanged.next(this.sortOrder);
}
}
Upvotes: 0
Views: 819
Reputation: 7682
So when you want to have several components using same logic while having different markups you neeed to simply create another component. Extend the one with the logic. And use all the benefits of OOP (inherited props and methods).
Upvotes: 1
Reputation: 439
I think you can just add new @Input() customCSSClasses: Object
to your generic component and pass the new CSS classes from host component and use ngClass
on selected elements to apply those custom classes (you need to add those custom classes in your global styles.css
file.)
For example:
// Host component.html
<sort-row [customCSSClasses]="{input: 'dark-input', select: 'dark-lg-select'}"
// the other config
></sort-row>
// sort-row component.ts
@Input() customCSSClasses?: Object;
// sort-row component.html
<input [ngClass]="customCSSClasses?.input ? customCSSClasses?.input : 'default-input'">
<select [ngClass]="customCSSClasses?.select ? customCSSClasses?.select : 'default-select'"></select
Upvotes: 0