Angular Ionic Firebase承诺,每次更改值时调用函数

Angular Ionic Firebase承诺,每次更改值时调用函数,angular,typescript,firebase,firebase-realtime-database,ionic2,Angular,Typescript,Firebase,Firebase Realtime Database,Ionic2,我想创建一个提供商,它是我的应用程序和Firebase之间的唯一接口。我是新手,如果我做错了什么,我会感到抱歉。我想做的是,每当某个值发生变化时,在FirebaseProvider外部调用一个函数。 FirebaseProvider: onUpdateLobby(键){ 返回新承诺((解决、拒绝)=>{ firebase.database().ref(“/games”).child(key).on('value',(snap)=>{ 控制台日志(“更新”); if(snap)解析(snap.v


我想创建一个提供商,它是我的应用程序和Firebase之间的唯一接口。
我是新手,如果我做错了什么,我会感到抱歉。我想做的是,每当某个值发生变化时,在FirebaseProvider外部调用一个函数。

FirebaseProvider:

onUpdateLobby(键){
返回新承诺((解决、拒绝)=>{
firebase.database().ref(“/games”).child(key).on('value',(snap)=>{
控制台日志(“更新”);
if(snap)解析(snap.val());
否则拒绝(错误(“onUpdateLobby错误”);
});
});

}
如我在评论中所述。我认为您遇到的问题是,您返回的是一个承诺,而不是
EventEmitter
。请尝试以下代码

Firebase提供商:

lobbyChanges = new EventEmitter<string>;

onUpdateLobby(key){
    firebase.database().ref("/games").child(key).on('value',(snap)=>{
        console.log("update");
        if (snap) this.lobbyChanges.emit(snap.val());
        else this.lobbyChanges.error(Error("onUpdateLobby Error"));
    });
}
this.db.lobbyChanges.subscribe(
    (snap) => {
        console.log(snap);
        // do stuff with the data
    (err) => {
        console.log(err);
});
this.db.onUpdateLobby('test')
export class FirebaseProvider{
    private gamesRef:any;

    constructor(){
        this.gamesRef = firebase.database().ref('games');
    }

    listenToGamesNode(key, callback){
        this.gamesRef.child(key).on('value', callback);
    }

    stopListeningToGamesNode(key){
        try{
            this.gamesRef.child(key).off('value');
        }
        catch(e){
            // Handle error
        }
    }
}
export class TestPage{
    private key:string = 'test';

    constructor(private firebaseProvider: FirebaseProvider){}

    ionViewWillEnter(){
        this.firebaseProvider.listenToGamesNode(this.key, this.callback);
    }

    ionViewWillLeave(){
        this.firebaseProvider.stopListeningToGamesNode(this.key);
    }

    private callback(snapshot){
        if(snapshot.exists()){
            console.log(snapshot.val());
        }
        else{
            // Handle missing node
        }
    }
}

我认为这是实现你想要的一种方式

FirebaseProvider
中创建一个公共函数(
listenToGamesNode()
),该函数将回调函数与子节点键一起作为参数。此函数注册侦听器,并在节点更改时调用提供的回调

stoplistingtogamesnode()
-函数删除侦听器

FirebaseProvider:

lobbyChanges = new EventEmitter<string>;

onUpdateLobby(key){
    firebase.database().ref("/games").child(key).on('value',(snap)=>{
        console.log("update");
        if (snap) this.lobbyChanges.emit(snap.val());
        else this.lobbyChanges.error(Error("onUpdateLobby Error"));
    });
}
this.db.lobbyChanges.subscribe(
    (snap) => {
        console.log(snap);
        // do stuff with the data
    (err) => {
        console.log(err);
});
this.db.onUpdateLobby('test')
export class FirebaseProvider{
    private gamesRef:any;

    constructor(){
        this.gamesRef = firebase.database().ref('games');
    }

    listenToGamesNode(key, callback){
        this.gamesRef.child(key).on('value', callback);
    }

    stopListeningToGamesNode(key){
        try{
            this.gamesRef.child(key).off('value');
        }
        catch(e){
            // Handle error
        }
    }
}
export class TestPage{
    private key:string = 'test';

    constructor(private firebaseProvider: FirebaseProvider){}

    ionViewWillEnter(){
        this.firebaseProvider.listenToGamesNode(this.key, this.callback);
    }

    ionViewWillLeave(){
        this.firebaseProvider.stopListeningToGamesNode(this.key);
    }

    private callback(snapshot){
        if(snapshot.exists()){
            console.log(snapshot.val());
        }
        else{
            // Handle missing node
        }
    }
}
然后在TestPage组件中,注入
FirebaseProvider
。使用lifecycle events
ionViewWillEnter
开始侦听,使用
ionViewWillLeave
停止侦听节点

测试页面:

lobbyChanges = new EventEmitter<string>;

onUpdateLobby(key){
    firebase.database().ref("/games").child(key).on('value',(snap)=>{
        console.log("update");
        if (snap) this.lobbyChanges.emit(snap.val());
        else this.lobbyChanges.error(Error("onUpdateLobby Error"));
    });
}
this.db.lobbyChanges.subscribe(
    (snap) => {
        console.log(snap);
        // do stuff with the data
    (err) => {
        console.log(err);
});
this.db.onUpdateLobby('test')
export class FirebaseProvider{
    private gamesRef:any;

    constructor(){
        this.gamesRef = firebase.database().ref('games');
    }

    listenToGamesNode(key, callback){
        this.gamesRef.child(key).on('value', callback);
    }

    stopListeningToGamesNode(key){
        try{
            this.gamesRef.child(key).off('value');
        }
        catch(e){
            // Handle error
        }
    }
}
export class TestPage{
    private key:string = 'test';

    constructor(private firebaseProvider: FirebaseProvider){}

    ionViewWillEnter(){
        this.firebaseProvider.listenToGamesNode(this.key, this.callback);
    }

    ionViewWillLeave(){
        this.firebaseProvider.stopListeningToGamesNode(this.key);
    }

    private callback(snapshot){
        if(snapshot.exists()){
            console.log(snapshot.val());
        }
        else{
            // Handle missing node
        }
    }
}

您在测试页面的何处运行此代码?需要注意的一点是,承诺不像可观察的那样有效。您需要调用函数以获得响应。