web-dev-qa-db-ja.com

Angular2の.map / .subscribeはどのように機能しますか?

Firebaseの3つの変数(配列)にAngularFire2を入力しようとしています。

DB構造は次のとおりです。

Firebase3 structure

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

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

何か案は?どうもありがとう

5
Kuba Chour

正しく理解できているかわかりませんので、お答えできれば幸いです。

したがって、このコードは次のとおりです。

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

Angular Firebaseはオブザーバブルを使用するため、リストオブジェクトを作成すると、オブザーバブルが返されます。最初のマップは、オブザーバブルの関数です。オブザーバブルが値を出力するたびに関数をマップできるため、基本的に、リストが変更されるたびに最初のマップが実行されます。このTodoのリストを見てください: enter image description here

これは非常に単純なアプリコンポーネントです。

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

コードは非常に単純で、混乱する可能性があるのは次の行だけです。

<FirebaseListObservable<any>> af.database.list('Todos').map(items 

あなたはこれでそれについてもっと読むことができます answer

これで、アプリをそのまま実行しても何も起こりません。コンソールには何もログインしません。どうして? Todosobservableを購読しているものがないからです。どうやって購読しますか?ビューで非同期パイプを使用する方法は2つあります。

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

または、コンポーネントのObservableを手動でサブスクライブします。

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

この非常に基本的なTodoアプリで簡単な Githubリポジトリ を作成しました。クローンを作成したい場合は、Firebaseデータベースをポイントしてください(すべての手順はREADMEファイル)、ローカルマシンで実行します。

これがアプリの外観です: enter image description here

12
Fabio Antunes