Angular 在NativeScript ListView中异步显示来自Firebase的消息

Angular 在NativeScript ListView中异步显示来自Firebase的消息,angular,typescript,firebase,rxjs,nativescript,Angular,Typescript,Firebase,Rxjs,Nativescript,我试图在ListView中异步显示简单消息。这些消息通过从Firebase获取。我不认为我的插件交互有任何问题,因为我能够初始化、登录甚至接收消息。我就是不能让它们显示在列表视图中 通过创建一个EventEmitter,我成功地将Firebase消息的事件回调映射到一个可观察的事件。我不确定这是否是正确的方法,但它已经显示了最好的结果,因为我可以看到通过我的可观察到的信息被推送 以下是我正在做的: import { Component, OnInit, EventEmitter } from "

我试图在ListView中异步显示简单消息。这些消息通过从Firebase获取。我不认为我的插件交互有任何问题,因为我能够初始化、登录甚至接收消息。我就是不能让它们显示在列表视图中

通过创建一个EventEmitter,我成功地将Firebase消息的事件回调映射到一个可观察的事件。我不确定这是否是正确的方法,但它已经显示了最好的结果,因为我可以看到通过我的可观察到的信息被推送

以下是我正在做的:

import { Component, OnInit, EventEmitter } from "@angular/core";
import { Observable } from "rxjs/Observable";
import * as firebase from "nativescript-plugin-firebase";
import { Message } from "./shared/message.model";
@Component({
    selector: "my-app",
    templateUrl: "app.component.html"
})
export class AppComponent implements OnInit {
    public messages: Observable<Array<Message>>;

    ngOnInit() {
        this.init()
            .then(() => this.login())
            .then(() => this.getMessages());
    }

   // ... implementations for init() and login(), also post()-method

    getMessages = () => {
        let msgs = [];
        // initialize with asynchronous behaviour
        let emitter = new EventEmitter(true);
        this.messages = emitter;
        // shows messages getting added to array
        this.messages.subscribe((a) => console.log(JSON.stringify(a)));

        firebase.addChildEventListener((result) => {
            msgs.push(new Message(result.value.text, result.value.timestamp));
            emitter.next(msgs);
        }, "/messages");
    }
}
<GridLayout rows="auto, *">
    <GridLayout row="0" columns="*, auto">
        <TextField #textInput hint="Type message..." col="0"></TextField>
        <Button text="Post" (tap)="post(textInput)" col="1"></Button>
    </GridLayout>

    <ListView row="1" [items]="messages | async">
        <template let-item="msg">
            <StackLayout>
                <Label text="a message"></Label> <!-- displays after button click -->
                <Label [text]="msg.text"></Label> <!-- results in exception when there even are items -->
            </StackLayout>
        </template>
    </ListView>
</GridLayout>

我做错了什么?为什么在NativeScript中实现异步列表如此困难,而在Angular中实现异步列表可以说很容易?此处的文档有点薄弱。

您的firebase连接器正在角度区域外运行,可能会将您的下一次呼叫包装在
ngZone中。运行
有助于:

import { Component, OnInit, EventEmitter, NgZone } from "@angular/core";
import { Observable } from "rxjs/Observable";
import * as firebase from "nativescript-plugin-firebase";
import { Message } from "./shared/message.model";
@Component({
    selector: "my-app",
    templateUrl: "app.component.html"
})
export class AppComponent implements OnInit {
    public messages: Observable<Array<Message>>;

    constructor(private ngZone: NgZone) {}

    ngOnInit() {
        this.init()
            .then(() => this.login())
            .then(() => this.getMessages());
    }

   // ... implementations for init() and login(), also post()-method

    getMessages = () => {
        let msgs = [];
        // initialize with asynchronous behaviour
        let emitter = new EventEmitter(true);
        this.messages = emitter;
        // shows messages getting added to array
        this.messages.subscribe((a) => console.log(JSON.stringify(a)));

        firebase.addChildEventListener((result) => {
            this.ngZone.run(() => {
                msgs.push(new Message(result.value.text, result.value.timestamp));
                emitter.next(msgs);
            });
        }, "/messages");
    }
}
从“@angular/core”导入{Component,OnInit,EventEmitter,NgZone};
从“rxjs/Observable”导入{Observable};
从“nativescript插件firebase”导入*作为firebase;
从“/shared/Message.model”导入{Message}”;
@组成部分({
选择器:“我的应用程序”,
templateUrl:“app.component.html”
})
导出类AppComponent实现OnInit{

公开消息:可观察到的

您的firebase连接器正在角度区域外运行,可能会将您的下一次呼叫包装到一个
ngZone中。运行
帮助:

import { Component, OnInit, EventEmitter, NgZone } from "@angular/core";
import { Observable } from "rxjs/Observable";
import * as firebase from "nativescript-plugin-firebase";
import { Message } from "./shared/message.model";
@Component({
    selector: "my-app",
    templateUrl: "app.component.html"
})
export class AppComponent implements OnInit {
    public messages: Observable<Array<Message>>;

    constructor(private ngZone: NgZone) {}

    ngOnInit() {
        this.init()
            .then(() => this.login())
            .then(() => this.getMessages());
    }

   // ... implementations for init() and login(), also post()-method

    getMessages = () => {
        let msgs = [];
        // initialize with asynchronous behaviour
        let emitter = new EventEmitter(true);
        this.messages = emitter;
        // shows messages getting added to array
        this.messages.subscribe((a) => console.log(JSON.stringify(a)));

        firebase.addChildEventListener((result) => {
            this.ngZone.run(() => {
                msgs.push(new Message(result.value.text, result.value.timestamp));
                emitter.next(msgs);
            });
        }, "/messages");
    }
}
从“@angular/core”导入{Component,OnInit,EventEmitter,NgZone};
从“rxjs/Observable”导入{Observable};
从“nativescript插件firebase”导入*作为firebase;
从“/shared/Message.model”导入{Message}”;
@组成部分({
选择器:“我的应用程序”,
templateUrl:“app.component.html”
})
导出类AppComponent实现OnInit{

公共消息:可见

除了与ngZone相关的问题外,项目模板中还有一个语法错误。将此
更改为

<template let-msg="item">


有关详细信息,请参阅。

除了与ngZone相关的问题外,项目模板中还有一个语法错误。请将此
更改为

<template let-msg="item">


有关详细信息,请参阅。

谢谢,这对我帮助很大。我的视图现在会枚举消息,但如果没有前一个“getView failed”,我仍然无法绑定到模板中消息的属性-例外。有什么想法吗?像Nick Iliev建议的那样修复了它Hanks,这对我很有帮助。我的视图现在枚举消息,但是如果没有前一个“getView failed”,我仍然无法绑定到模板中消息的属性-例外。有什么想法吗?像Nick Iliev建议的那样修复了它。你是正确的,我通过在某个步骤中将其命名为“项目”使其工作,但我没有完全理解我为修复它所做的工作。非常感谢你的帮助,很遗憾,我只能接受一个正确的答案。你是正确的,我通过将其命名为“项目”使其工作在某个步骤中,我没有完全理解我做了什么来修复它。非常感谢你的帮助,很遗憾,我只能接受一个正确的答案。