Last active
July 24, 2019 18:20
-
-
Save vmasek/49542101a8ddd74a342f90b95faa3225 to your computer and use it in GitHub Desktop.
Structural directives - Range directive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This interface represents context of the directive | |
*/ | |
interface RangeContext { | |
$implicit: number; // current item exposed as implicit value, enables declaring in template variable via let keyword | |
index: number; // current index of the item | |
first: boolean; // indicates if the item is first in the collection | |
last: boolean; // indicates if the item is last in the collection | |
} | |
@Directive({ | |
selector: '[appRange]' | |
}) | |
export class RangeDirective { | |
@Input() | |
set appRange(value: [number, number] | number) { | |
this.viewRef.clear(); | |
const [from, to] = Array.isArray(value) ? value : [0, value]; | |
const range = this.generateRange(from, to); | |
range.forEach( | |
(itemNumber, index) => this.viewRef.createEmbeddedView(this.templateRef, { | |
$implicit: itemNumber, | |
index, | |
first: index === 0, | |
last: index + 1 === range.length, | |
}) | |
); | |
} | |
constructor(private readonly viewRef: ViewContainerRef, | |
private readonly templateRef: TemplateRef<RangeContext>) { | |
} | |
/** | |
* Generates and array of N items (N is difference between to and from). | |
* Item values are starting at `from` value and ending with `to` value. | |
* | |
* @param from - default is 0 | |
* @param to - items will be generated up to this value | |
* - example: 7 will result in output [..., 4, 5, 6] | |
*/ | |
private generateRange(from: number = 0, to: number): number[] { | |
return Array.from({length: (to - from)}, (_, index) => index + from); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div *appRange="maxElements; let num; let i = index"> | |
index: {{i}} | element: {{num + 1}} of {{maxElements}} | |
</div> | |
<label> | |
Year: | |
<select> | |
<ng-container *appRange="[2005, 2018]; let num"> | |
<option [value]="num">{{num}}</option> | |
</ng-container> | |
</select> | |
</label> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://itnext.io/angular-structural-directives-b54ea21b39a7