Angular4: How do I *ngFor, for every number in an int?
我的组件中有一个名为" count"的int属性。
我想显示一个p标签X次,其中X是我的count属性等于的int。除了弄乱假数组,真的没有简单的方法可以做到这一点吗?
您可以使用管道过滤器轻松完成此操作,该过滤器根据过滤器参数= number将空数组转换为多个子级。
管道过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'range', pure: false }) export class RangePipe implements PipeTransform { transform(items: any[], quantity: number): any { items.length = 0; for (let i = 0; i < quantity; i++) { items.push(i); } return items; } } |
看法
1 |
Plnkr:https://plnkr.co/edit/Yn775KSbBeUPeyaI9sep?p=preview
您可以创建另一个名为countObservable
的变量。
1 | countObservable = Observable.range(0, this.count).toArray(); |
在HTML中将异步用于
1 | <p *ngFor="let num of countObservable | async">Hello {{num}} |
更新
如果需要更新号码,可以使用
代替上面的countObservable代码,使用此
1 2 3 | count$= new BehaviorSubject(10); countObservable$ = this.count$.flatMap(count => Observable.range(0, count).toArray()) ; |
要更改数字值,只需更新
1 | this.count$.next(newNum); |
我有点不喜欢每次要渲染元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import { Directive, Input, TemplateRef, ViewContainerRef, isDevMode, EmbeddedViewRef } from '@angular/core'; export class ForNumberContext { constructor(public count: number, public index: number) { } get first(): boolean { return this.index === 0; } get last(): boolean { return this.index === this.count - 1; } get even(): boolean { return this.index % 2 === 0; } get odd(): boolean { return !this.even; } } @Directive({ selector: '[ForNumber]' }) export class ForNumberDirective { @Input() set forNumberOf(n: number) { this._forNumberOf = n; this.generate(); } private _forNumberOf: number; constructor(private _template: TemplateRef<ForNumberContext>, private _viewContainer: ViewContainerRef) { } @Input() set ngForTemplate(value: TemplateRef<ForNumberContext>) { if (value) { this._template = value; } } private generate() { for (let i = 0; i < this._forNumberOf; i++) { this._viewContainer.createEmbeddedView(this._template, new ForNumberContext(this._forNumberOf, i)); } } } |
然后您可以按以下方式使用它:
1 2 | <ng-template ForNumber [forNumberOf]="count" let-index="index"> <span>Iteration: {{index}}!</span></ng-template> |
请注意,我还没有对其进行广泛的测试,所以我不能保证它的防弹性能:)
根据Angular文档:
createEmbeddedView() Instantiates an embedded view and inserts it into this container. it accepts a context object as second parameter:
abstract createEmbeddedView(templateRef: TemplateRef, context?: C, index?: number): EmbeddedViewRef .
当angular通过调用createEmbeddedView创建模板时,它也可以传递将在
使用上下文可选参数,您可以在组件中使用它
就像使用* ngFor。
一样,将其提取到模板中。
app.component.html:
1 2 3 4 5 6 7 8 | <p *for="randomNumber; let i = index; let first = first; let last = last; let even = even, let odd = odd; length = length"> index :{{i}}, length:{{length}}, is first : {{first}}, is last : {{last}}, is even : {{even}}, is odd : {{odd}} </p> |
for.directive.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import { Directive, Input, TemplateRef, ViewContainerRef, EventEmitter } from '@angular/core'; @Directive({ selector: '[for]' }) export class ForDirective { constructor( private templateRef: TemplateRef, private viewContainer: ViewContainerRef) { } @Input('for') set loop(num: number) { for (var i = 0; i < num; i++) this.viewContainer.createEmbeddedView( this.templateRef, { index: i, odd: i % 2 == 1, even: i % 2 == 0, first: i == 0, last: i == num, length: num - 1, } ); } } |