在*ngFor中使用管道,页面有时更新,有时不更新

Using pipe in *ngFor, the page sometimes updates, sometimes not

我正在使用 angular2-meteor,我已经在使用 pure: false。但是管道有时 运行,有时不是。有关问题的详细信息,请参阅我在代码中的评论。

谢谢

<div *ngFor="#user of (users|orderByStatus)">
    {{user.status.online}}
</div>


users:Mongo.Cursor<Meteor.User>;
ngOnInit()
{
    this.subscribe('users', () => {
        this.autorun(() => {
            this.users = Meteor.users.find();
        });
    }, true);
}

import {Pipe} from 'angular2/core';

@Pipe({
    name: 'orderByStatus',
    pure: false
})
export class OrderByStatusPipe {
    transform(usersCursor:Mongo.Cursor<Meteor.User>):Array<Meteor.User> {
        console.log("OrderByStatusPipe runs");

        // (1) If I only do these two lines, the change of other users' status can show on the screen immediately. 
        // let users = usersCursor.fetch();
        // return users;

        // (2) If sort users by status, the page sometimes updates, sometimes not when user status change.
        //  If not update automatically, I click that part of screen, it will update then.
        let users:Array<Meteor.User> = usersCursor.fetch();
        users.sort((a, b) => {
            return (a.status.online === b.status.online) ? 0 : (a.status.online ? -1 : 1);
        });
        return users;
    }
}

我不知道调用 Meteor.users.find()usersCursor.fetch() 背后的具体内容,但我认为您的用户检索应该在过滤器本身之外完成。我想一部分是在过滤器中完成的(usersCursor.fetch()?)这可能是问题所在...

更新:错误似乎是 fixed

我认为问题与 angular2-meteor 有关。

最后,当您尝试从 Mongo 获取数据时,我找到了使用 sort 的有效方法。所以不再使用排序管道了。

但是你不能在*ngFor中使用users:Mongo.Cursor<Meteor.User>,需要先使用fetch()再使用Array<Meteor.User>,否则列表顺序改变时会报错:

Cannot read property 'status' of undefined

但是列表不会在 UI 中自动更新。所以你需要使用 NgZone.

所以最终的工作代码是这样的:

<div *ngFor="#user of users)">
    {{user.status.online}}
</div>


users:Array<Meteor.User>;  // here cannot use users:Mongo.Cursor<Meteor.User>
constructor(private _ngZone:NgZone) {}
ngOnInit()
{
    this.subscribe('users', () => {
        this.autorun(() => {
            this._ngZone.run(() => {
                this.users = Meteor.users.find().fetch();
            });
        });
    }, true);
}