Angular4:如何为 int 中的每个数字 *ngFor?
Angular4: How do I *ngFor, for every number in an int?
我的组件中有一个名为 "count" 的整数 属性。
我想显示 p 标签 X 次,其中 X 是我的计数 属性 等于的整数。除了弄乱假数组之外,真的没有简单的方法可以做到这一点吗?
我有点不喜欢每次我想渲染一个元素 n
次时创建一个大小为 n
的空数组的方法,所以我创建了一个自定义结构指令:
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));
}
}
}
然后您可以按如下方式使用它:
<ng-template ForNumber [forNumberOf]="count" let-index="index">
<span>Iteration: {{index}}!</span></ng-template>
请注意,我还没有对它进行广泛的测试,所以我不能保证它是防弹的:)
您可以轻松地做到这一点 管道过滤器,它根据过滤器参数将空数组转换为多个子数组 =数.
管道过滤器
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;
}
}
查看
<div *ngFor="let n of [] | range:100"></div>
Plnkr: https://plnkr.co/edit/Yn775KSbBeUPeyaI9sep?p=preview
您可以创建另一个名为 countObservable 的变量
countObservable = Observable.range(0, this.count).toArray();
在 HTML
中使用异步
<p *ngFor="let num of countObservable | async" >Hello {{num}}</h2>
更新
如果我们需要更新号码,我们可以使用 flatMap
。
不要使用上面的 countObservable 代码,而是使用这个
count$= new BehaviorSubject(10);
countObservable$ =
this.count$.flatMap(count => Observable.range(0, count).toArray()) ;
要更改数字值,只需更新 count$
this.count$.next(newNum);
根据 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 创建模板时,它还可以传递将在 ng-template
.
中使用的上下文
使用上下文可选参数,你可以在组件中使用它
就像使用 *ngFor.
一样在模板中提取它
app.component.html:
<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:
import { Directive, Input, TemplateRef, ViewContainerRef, EventEmitter } from '@angular/core';
@Directive({
selector: '[for]'
})
export class ForDirective {
constructor(
private templateRef: TemplateRef<any>,
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,
}
);
}
}
我用 :
解决了它
在 TS:
months = [...Array(12).keys()];
在模板中:
<p *ngFor="let month of months">{{month+1}}</p>
我的组件中有一个名为 "count" 的整数 属性。
我想显示 p 标签 X 次,其中 X 是我的计数 属性 等于的整数。除了弄乱假数组之外,真的没有简单的方法可以做到这一点吗?
我有点不喜欢每次我想渲染一个元素 n
次时创建一个大小为 n
的空数组的方法,所以我创建了一个自定义结构指令:
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));
}
}
}
然后您可以按如下方式使用它:
<ng-template ForNumber [forNumberOf]="count" let-index="index">
<span>Iteration: {{index}}!</span></ng-template>
请注意,我还没有对它进行广泛的测试,所以我不能保证它是防弹的:)
您可以轻松地做到这一点 管道过滤器,它根据过滤器参数将空数组转换为多个子数组 =数.
管道过滤器
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;
}
}
查看
<div *ngFor="let n of [] | range:100"></div>
Plnkr: https://plnkr.co/edit/Yn775KSbBeUPeyaI9sep?p=preview
您可以创建另一个名为 countObservable 的变量
countObservable = Observable.range(0, this.count).toArray();
在 HTML
中使用异步 <p *ngFor="let num of countObservable | async" >Hello {{num}}</h2>
更新
如果我们需要更新号码,我们可以使用 flatMap
。
不要使用上面的 countObservable 代码,而是使用这个
count$= new BehaviorSubject(10);
countObservable$ =
this.count$.flatMap(count => Observable.range(0, count).toArray()) ;
要更改数字值,只需更新 count$
this.count$.next(newNum);
根据 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 创建模板时,它还可以传递将在 ng-template
.
使用上下文可选参数,你可以在组件中使用它 就像使用 *ngFor.
一样在模板中提取它app.component.html:
<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:
import { Directive, Input, TemplateRef, ViewContainerRef, EventEmitter } from '@angular/core';
@Directive({
selector: '[for]'
})
export class ForDirective {
constructor(
private templateRef: TemplateRef<any>,
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,
}
);
}
}
我用 :
解决了它在 TS:
months = [...Array(12).keys()];
在模板中:
<p *ngFor="let month of months">{{month+1}}</p>