Angular2上的.map/.subscribe是如何工作的?

Kub*_*our 5 firebase firebase-realtime-database ionic2 angularfire2 angular

我正在尝试使用AngularFire2从Firebase填充3个变量(数组).

DB结构是这样的:

Firebase3结构

我坚持认为我应该如何解决Promise来映射以填充这些变量.即使最简单的查询也不会返回任何内容,并且console.log也不显示任何内容.

    let testConnection = this.AngularFire.database.list(DbPath)
          .map((items) => {
            console.log(items);
            return items.map(item => {
                console.log(items);
                 console.log(item);
   })})
Run Code Online (Sandbox Code Playgroud)

我试过.subscribe,但由于这保留了快照(并且没有保留它不起作用),这对我来说是不可行的:/.但它起作用并填补了它.

return this.AngularFire.database.list(DbPath, { preserveSnapshot: true })
.subscribe(
(snapshots:any) => {
    snapshots.forEach(snapshot => {
    console.log(snapshot.key);

       if (snapshot.key === 'disliked') {
       this.dataListDisliked = snapshot.val();
   }
   ...
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?非常感谢

Fab*_*nes 12

我希望我能回答你的问题,因为我不知道我是否理解正确.

所以这段代码:

let testConnection = this.AngularFire.database.list(DbPath)
  .map((items) => { //first map
    console.log(items);
    return items.map(item => { //second map
      console.log(items);
      console.log(item);
    })
  })
Run Code Online (Sandbox Code Playgroud)

我将尝试为您分解,Angular Firebase使用observable,因此当您创建一个列表对象时,它会返回一个Observable.因此,您的第一个映射是来自observable的函数,它允许您在每次observable发出值时映射函数.所以基本上你的第一张地图会在你的清单每次更改时运行.看看这个Todos列表: 在此输入图像描述

现在这是一个非常简单的应用程序组件:

import { Component } from '@angular/core';
import { AngularFire, FirebaseListObservable } from 'angularfire2';
import 'rxjs/add/operator/map'; // you might need to import this, or not depends on your setup

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';
  text = '';
  todos: FirebaseListObservable<any[]>;
  constructor(af: AngularFire) {
    this.todos = <FirebaseListObservable<any>> af.database.list('Todos').map(items => { //first map
          return items.map(item => { //second map
            item.text = item.text.toUpperCase();
            return item;
          })
        });
  }

  addTodo() {
    this.todos.push({
      text: this.text,
      completed: false
    });
    this.text = '';
  }

  changeTodo(key: string, completed){
    this.todos.update(key, {completed: !completed});
  }
}
Run Code Online (Sandbox Code Playgroud)

代码非常简单,唯一可能令人困惑的是这一行:

<FirebaseListObservable<any>> af.database.list('Todos').map(items 
Run Code Online (Sandbox Code Playgroud)

您可以在此答案中阅读更多相关信息

现在如果您按原样运行我们的应用程序,则不会发生任何事情.什么都不会记录到我们的控制台.为什么?好吧,因为没有订阅我们的Todos观察.我们如何订阅?我们有两种方法,在视图上使用异步管道:

<li *ngFor="let todo of todos | async" [ngClass]="{completed: todo.completed}" (click)="changeTodo(todo.$key, todo.completed)">
    {{ todo.text }}
  </li>
Run Code Online (Sandbox Code Playgroud)

或者在我们的组件上手动订阅我们的Observable:

this.todos.subscribe(todos => {
  //now we can assign our todos to a variable
  this.ourTodoList = todos;
});
Run Code Online (Sandbox Code Playgroud)

我用这个非常基本的Todo应用程序创建了一个简单的Github仓库,如果你想要你可以克隆它,指向你的Firebase数据库(所有指令都在README文件中)并在你的localmachine上运行.

这是应用程序的外观: 在此输入图像描述