Ich versuche, einfache Nachrichten asynchron in einer ListView anzuzeigen. Die Nachrichten werden von Firebase über the de-facto standard NativeScript Plugin abgerufen. Ich denke nicht, dass irgendetwas mit meiner Plugin-Interaktion falsch ist, da ich in der Lage bin, die Nachrichten zu initialisieren, einzuloggen und sogar zu empfangen. Ich kann sie einfach nicht in einem ListView anzeigen lassen.Anzeigen von Nachrichten aus Firebase asynchron in NativeScript ListView
Ich habe es geschafft, den Event-Callback von der Firebase-Nachricht abzubilden, indem ich durch Erstellen eines EventEmitter auf eine Observable drängte. Ich bin mir nicht sicher, ob dies der richtige Weg ist, aber es hat die besten Ergebnisse gezeigt, da ich sehen kann, dass die Nachrichten durch mein Observable geschoben werden.
Hier ist, was ich tue:
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");
}
}
Und dies ist die Ansicht:
<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>
ich, dass das Abonnement so weit sehen arbeitet wie jede Array-Variante angemeldet wird schrittweise, aber meine Ansicht zeigt sie nicht an. Ich habe verschiedene Modi für die ChangeDetectionStrategie versucht, die keinen Unterschied zu machen schien.
Ich fand heraus, dass wenn ich einen Knopf in meiner Ansicht habe, der eine Komponentenfunktion aufruft, kann ich die Elemente sehen, nachdem ich darauf geklickt habe. Doch wenn es Bindungen an das let-Variable in meiner Ansicht wie [text]="msg.text"
stürzt die Anwendung mit dem folgenden Fehler:
An uncaught Exception occurred on "main" thread.
com.tns.NativeScriptException:
Calling js method getView failed
[object Object]
File: "/data/data/org.nativescript.firebasetest/files/app/tns_modules/@angular/core/bundles/core.umd.js, line: 9464, column: 20
StackTrace:
Frame: function:'ListViewComponent.detectChangesOnChild', file:'/data/data/org.nativescript.firebasetest/files/app/tns_modules/nativescript-angular/directives/list-view-comp.js', line: 134, column: 29
Frame: function:'ListViewComponent.onItemLoading', file:'/data/data/org.nativescript.firebasetest/files/app/tns_modules/nativescript-angular/directives/list-view-comp.js', line: 114, column: 14
Frame: function:'Observable.notify', file:'/data/data/org.nativescript.firebasetest/files/app/tns_modules/data/observable/observable.js', line: 146, column: 32
Frame: function:'ListViewAdapter.getView', file:'/data/data/org.nativescript.firebasetest/files/app/tns_modules/ui/list-view/list-view.js', line: 199, column: 28
// ... native stacktrace
Was mache ich falsch? Warum muss es so schwierig sein, eine Async-Liste in NativeScript zu implementieren, wenn es in Angular wohl einfach ist? Die Dokumentation ist ein bisschen hier schwach ..
Danke, das hat mir sehr geholfen. Meine Ansicht listet nun die Nachrichten auf, aber ich kann immer noch nicht an Eigenschaften einer Nachricht in meiner Vorlage binden, ohne die frühere "getView failed" -Ausnahme zu erhalten. Irgendwelche Ideen dazu? – nilo
Behoben, dass es wie Nick Iliev vorgeschlagen – nilo