I cannot update the UI immediately after subscribing the data from database, I have to click somewhere
Also if I use the router to go to another page, it does not work
@Component({
selector: 'foo-component',
template: `
{{foo}}
`
})
export class FooComponent extends MeteorComponent {
foo: string ;
constructor() {
super();
this.subscribe('messages', () => {
// I cannot change foo value immediately, I have to click somewhere
this.foo = 'foo';
// Also if I use the router to go to another page, it does not work
// this.router.navigate(['Home']);
});
}
}
How to solve this?
Note the new angular2-meteor version
autoBind
is set to true by default. So you probably won't meet this issue again.But you still need use NgZone in Accounts.changePassword or other similar Accounts.foo() functions.
This problem is because that part of code run out of Angular 2 zone, you need run it inside of zone to update UI immediately or use router to go to another page.
Most time you don't do this. So when do you need this? Usually in callback of Meteor functions:
this.autorun(() => {
// here you need
});
this.subscribe('messages', () => {
// here you need
});
this.call('newMessage', (error, result) => {
// here you need
});
Accounts.changePassword(currentPassword, newPassword, error => {
// here you need
});
Take
this.call('newMessage', (error, result) => {
this.router.navigate(['Home']);
});
for example, you need change to:
import { NgZone } from '@angular/core';
constructor(private zone: NgZone) {}
this.call('newMessage', (error, result) => {
this.zone.run(() => {
this.router.navigate(['Home']);
});
});
Luckily, Angular2-Meteor helps you do this dirty work.
Check Angular2-Meteor API document, there is an autoBind
parameter for this.subscribe
and this.autorun
.
So now you don't need use this.zone.run
, instead you can just add a true
:
this.autorun(() => {
// your code
}, true);
this.subscribe('messages', () => {
// your code
}, true);