- Hayden Braxton
Â
- Composition vs Inheritance
- Compound Components
- Semantic Inputs and Template Inputs
- Render Prop
- State Reducer
Code Smell 👃💩
@Component({
selector: 'this-is-painful',
template: `
<h3>too bad I don't inherit any template or styles from my parent</h3>
<p>
something from parent {{parentProperty}}.
It's really clear where this data came from 🙃
</p>
<button (click)="parentHandler()">redundant plumbing</button>
`
})
export class InheritanceComponent extends ParentComponent {
constructor(
private myDependency: CoolService,
private anotherDep: AnotherService,
private parentDep: DontKnowWhyService,
private anotherForTheParent: SomeService
) {
// hope i got the access modifiers right ...
// hope I got these in the right order ...
// I'm sure this is scalable ¯\_(ツ)_/¯
super(parentDep, anotherForTheParent);
}
}
Code Smell 👃💩
@Component({
selector: 'list-page',
template: `
<h1>List of Cool Things</h1>
<cool-list-item
*ngFor="let item of list; let i = $index;"
[selected]="isSelected(i)"
(click)="selectItem(i)"
[item]="item"
></cool-list-item>
`
})
export class MaybeShouldBeCompoundComponent {
private selectedIndex: number;
list = [...]; // or maybe I got this from a service
isSelected = (index: number) => index === this.selectedIndex;
selectItem = (index: number) => this.selectedIndex = index;
}
Code Smell 👃💩
@Component({
selector: 'this-is-fine',
template: `
<h3>innerHtml all the things!</h3>
<!-- too bad my styles dont apply to the innerHtml result -->
<div
class="message"
[innerHtml]="someRichText"
></div>
`,
styles: [`.message p { color: orange }`]
})
export class RichTextComponent {
@Input() someRichText = `
<h1>default title</h1>
<p>default paragraph that won't be orange</p>
`;
}
Code Smell 👃💩
@Component({
selector: 'one-size-fits-all',
template: `
<div [ngClass]="getClass()">
<div
*ngIf="configSwitch && configOption === 'option1'"
(click)="doTheThing()"
>display like this</div>
<div
*ngIf="configSwitch && configOption === 'option2'"
(click)="doTheThing()"
>display it different</div>
<div
*ngIf="!configSwitch"
(click)="doTheThing()"
>display another thing</div>
</div>
`,
styles: [`.message p { color: orange }`]
})
export class DisplayManyCasesComponent {
@Input() configOption: string;
@Input() configSwitch: boolean;
getClass = () => ({ [this.configOption]: true });
doTheThing = () => {...}
}
Code Smell 👃💩
@Component({
selector: 'doing-too-many-things',
template: `<button (click)="doTheThing">Do the thing</button>`,
})
export class DoingTooManyThingsComponent {
@Input() configOption: string;
@Input() configSwitch: boolean;
doTheThing = () => {
if (configSwitch && configOption === 'option1') {
// do it like this
} else if (configSwitch && configOption === 'option2') {
// do it like that
} else if (!configSwitch) {
// handle a different case
} else {
// this is very scalable ¯\_(ツ)_/¯
}
}
}