我试图创建一个带有 angular 2 的应用程序,我希望在 *ngFor 中呈现最后一个元素时,执行一个函数,如下所示:
<ul>
<li *ngFor="#i of items">{{i.text}}</li> <==== i want when this completed, execute a functuon in my class
</ul>
谢谢。
我试图创建一个带有 angular 2 的应用程序,我希望在 *ngFor 中呈现最后一个元素时,执行一个函数,如下所示:
<ul>
<li *ngFor="#i of items">{{i.text}}</li> <==== i want when this completed, execute a functuon in my class
</ul>
谢谢。
您可以@ViewChildren
为此目的使用
有三种情况
1. on 初始化ngFor
元素没有被渲染,因为ngIf
它或者它的父元素
ngIf
变得真实时,您将收到ViewChildren
订阅通知2. 初始化ngFor
元素被渲染,不管ngIf
它是在它还是它的父元素上
ViewChildren
订阅不会第一次通知你,但你可以确定它是在ngAfterViewInit
钩子中呈现的3. 向/从ngFor
数组中添加/删除项目
ViewChildren
订阅也会通知您[Plunker Demo] (请参阅那里的控制台日志)
@Component({
selector: 'my-app',
template: `
<ul *ngIf="!isHidden">
<li #allTheseThings *ngFor="let i of items; let last = last">{{i}}</li>
</ul>
<br>
<button (click)="items.push('another')">Add Another</button>
<button (click)="isHidden = !isHidden">{{isHidden ? 'Show' : 'Hide'}}</button>
`,
})
export class App {
items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
@ViewChildren('allTheseThings') things: QueryList < any > ;
ngAfterViewInit() {
this.things.changes.subscribe(t => {
this.ngForRendered();
})
}
ngForRendered() {
console.log('NgFor is Rendered');
}
}
<ul>
<li *ngFor="let i of items; let last = last">{{i}} {{last ? callFunction(i) : ''}}</li>
</ul>
这是无用的,除非与changeDetectionStrategy.OnPush 一起使用
然后您可以控制发生变化检测的次数,从而控制您的函数被调用的次数。
即:您可以changeDetection
在数据items
更改时触发 next,您的函数将给出正确的指示,ngFor
为真正的更改呈现。
我使用了一些其他人抱怨的方法的小技巧,它的作用就像一个魅力:
<ul>
<li *ngFor="let i of items; let last = last">{{i}} {{last ? callFunction(i) : ''}}</li>
</ul>
然后在您的组件中:
shouldDoIt = true; // initialize it to true for the first run
callFunction(stuff) {
if (this.shouldDoIt) {
// Do all the things with the stuff
this.shouldDoIt = false; // set it to false until you need to trigger again
}
}
这并没有解决这种方法的问题根源,但它是一种成本极低的黑客,使我的应用程序运行顺利。我确实希望 Angular 团队能够实现一种更友好的方式来在 *ngFor 加载其内容后触发一些代码。
你可以通过使用#last
of获取最后一个索引来做同样的事情,*ngFor
并通过获取最后一个索引值来调用函数,然后做任何你想做的事情。这是相同的代码 -
<ul>
<li *ngFor="#item of items; #last = last">
<span *ngIf='last'>{{hello(last)}}</span>
{{item}}
</li>
</ul>
items: Array<number> = [1,2,3,4,5]
constructor() { console.clear();}
hello(a){
if(a==true)
this.callbackFunction();
}
callbackFunction(){
console.log("last element");
}
相同的工作示例 Working Plunker
我也遇到了这个问题。就我而言,我正在调用 Web 服务来检索数据,并且需要执行 javascript 来初始化由*ngFor
. 这是我想出的:
updateData() {
this.dataService.getData().subscribe(
function(data) {
this.data = data;
setTimeout(javascriptInitializationFunction, 0);
},
function(err) { /* handle it */ }
);
}
setTimout
在执行之前会等待 DOM 更新。这不完全是你问的,但希望它有所帮助。
我面临同样的问题,并找到一种方法来解决这个问题。不确定它是否适合您。
前提条件是您使用 ngFor 来呈现入站属性。
上下文:从后端获取网格数据后,我需要调用 MDL 的 upgradeAllRegistered 来使复选框变得漂亮。
我在 'ngOnChanges' 中添加了一个 setTimeout;
grid.componet.ts:
export class GridComponent {
@Input() public rows: Array<any>;
ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
for (let propName in changes) {
if (propName == 'rows') {
setTimeout(() => componentHandler.upgradeAllRegistered());
}
}
}
}
grid.component.html:
<tr #rowDOM *ngFor="let row of rows;"></tr>