I have simple app that inserts new record to Firebase and below the input field it simply lists last 10 items in database.
PROBLEM:
- I need to start inputing someting to input field or to click on "update" for data from Firebase to appear in my listing. It seems that data comes in after the processing by angular has been already done, causing it now to show the list initialy. I tried adding "| async" to ngFor, but does not work and causes errors in console. Everything is working good, just need to load and show the data onload, without me inputing a keystroke in input or clicking to update button.
- when I open two tabs with same app, they do not update realtime as I supposed they would once I start inputing data zig-zag from one tab to another, I only appears in the tab in which I inserted the data.
import {Component,enableProdMode} from 'angular2/core'; enableProdMode();
import {FirebaseService} from 'firebase-angular2/core';
var myFirebaseRef = new Firebase("https://xxx.firebaseio.com/messages");
@Component({
selector: 'my-app',
template: `
<input type=text [(ngModel)]="newmsg" #newmsgref (keyup.enter)="updateHello(newmsgref)">
<button (click)="updateHello(newmsgref)">Update</button>
<ul>
<li *ngFor="#item of items">
{{item}}
</li>
</ul>
`
})
export class AppComponent {
newmsg:string;
items:Array<string>=[];
constructor() {
myFirebaseRef.limitToLast(10).on('child_added', (childSnapshot, prevChildKey) => {
childSnapshot.forEach((records) => {
this.items.push(records.val());
});
});
}
updateHello(r){
myFirebaseRef.push({
title: this.newmsg
});
this.newmsg="";
r.focus();
}
}
SOLUTION #1 WITH NGZONE MANUAL UPDATE WHICH WORKED (thanks to: Günter Z?chbauer)
Since the definition was outside the A2, the use of NgZone is really easy and corrected the problem. Thanks Günter ;)
import {Component,enableProdMode,NgZone} from 'angular2/core'; enableProdMode();
import {FirebaseService} from 'firebase-angular2/core';
var myFirebaseRef = new Firebase("https://xxx.firebaseio.com/messages");
@Component({
selector: 'my-app',
template: `
<input type=text [(ngModel)]="newmsg" #newmsgref (keyup.enter)="updateHello(newmsgref)">
<button (click)="updateHello(newmsgref)">Update</button>
<ul>
<li *ngFor="#item of items">
{{item}}
</li>
</ul>
`
})
export class AppComponent {
newmsg:string;
items:Array<string>=[];
constructor(private zone: NgZone) {
myFirebaseRef.limitToLast(10).on('child_added', (childSnapshot, prevChildKey) => {
zone.run(() => {
childSnapshot.forEach((records) => {
this.items.push(records.val());
});
});
});
}
updateHello(r){
myFirebaseRef.push({
title: this.newmsg
});
this.newmsg="";
r.focus();
}
}
SOLUTION #2 AUTOMATIC A2 UPDATING WHICH WORKED (thanks to: Thierry)
I simply put the definition inside the class of angular2, not outside, and everything started working as I assumed initialy. Thank you Thierry for the insight ;).
import {Component,enableProdMode} from 'angular2/core'; enableProdMode();
import {FirebaseService} from 'firebase-angular2/core';
@Component({
selector: 'my-app',
template: `
<input type=text [(ngModel)]="newmsg" #newmsgref (keyup.enter)="updateHello(newmsgref)">
<button (click)="updateHello(newmsgref)">Update</button>
<ul>
<li *ngFor="#item of items">
{{item}}
</li>
</ul>
`
})
export class AppComponent {
newmsg:string;
items:Array<string>=[];
myFirebaseRef = new Firebase("https://xxx.firebaseio.com/messages");
constructor() {
this.myFirebaseRef.limitToLast(10).on('child_added', (childSnapshot, prevChildKey) => {
childSnapshot.forEach((records) => {
this.items.push(records.val());
});
});
}
updateHello(r){
this.myFirebaseRef.push({
title: this.newmsg
});
this.newmsg="";
r.focus();
}
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…