angular2 firebase实时更新无法正常工作

时间:2016-02-03 12:36:20

标签: firebase angular

我有一个简单的应用程序,它将新记录插入Firebase,在输入字段下方,它只列出数据库中的最后10个项目。

问题:

  1. 我需要开始输入某些输入字段或点击“更新”,以便Firebase中的数据显示在我的列表中。看来,在处理完角度后数据已经完成,现在它已经初始化地显示了列表。我尝试将“| async”添加到ngFor,但不起作用并导致控制台出错。一切都运行良好,只需要加载并显示数据onload,而无需在输入中输入击键或点击更新按钮。
  2. 当我用相同的应用程序打开两个选项卡时,它们不会实时更新,因为我认为一旦我开始从一个选项卡输入数据zig-zag到另一个选项卡,我只会出现在我插入数据的选项卡中。 / LI>
    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();
        }
    }
    

    解决方案#1与NGZONE MANUAL UPDATE 工作原理(感谢:GünterZöchbauer) 由于定义在A2之外,因此使用NgZone非常容易并且纠正了问题。谢谢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();
        }
    }
    

    解决方案#2自动A2更新哪些工作(感谢:Thierry) 我只是将定义放在angular2的类中,而不是在外面,并且一切都按照我的假设开始工作。感谢Thierry的见解;)。

    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();
        }
    }
    

2 个答案:

答案 0 :(得分:5)

constructor(private zone: NgZone)

...
zone.run(() => {
  childSnapshot.forEach((records) => {
    this.items.push(records.val());
  });
});
...

另见Triggering Angular2 change detection manually

答案 1 :(得分:4)

Günter确切地指出了问题;-)实际上myFirebaseRef是在Angular2处理之外创建的。

如果您对Firebase的自定义管道感兴趣,可以查看Sarah Robinson在Angular Connect 2015上的演讲的来源:

希望它可以帮到你, 亨利