Angular 2如何在填充数组后运行函数

时间:2017-06-14 07:10:10

标签: angular typescript rxjs

组件:

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

import { AF } from '../angularfire.service';

@Component({
  selector: 'app-add-friend',
  templateUrl: './add-friend.component.html',
  styleUrls: ['./add-friend.component.less']
})
export class AddFriendComponent implements OnInit {
  profileInfo = [];
  currentUser = [];
  requestToggle: boolean = false;
  showButtons: boolean = true;

  constructor(private afService: AF, private route: ActivatedRoute, private router: Router) {
    let id = this.route.snapshot.params['id'];

    // Get viewed profile details.
    this.afService.getAthleteProfile(id).subscribe((data) => {
      if (data.length > 0) {
        let details = data[0];
        this.profileInfo.push(details);
      }
    });

    // Get current logged in user details.
    afService.getCurrentUserInfo().then(currentUserDetails => {
      this.currentUser.push(currentUserDetails);
    });
  }

  // Send friend request.
  addFriend() {
    this.afService.addFriendRequest(this.profileInfo[0].userID, this.currentUser[0].userID, this.profileInfo[0].firstName, this.profileInfo[0].lastName, this.currentUser[0].firstName, this.currentUser[0].lastName).then(() => {

    });
  }

  ngOnInit() {
    // Check if friend request has been sent to display appropriate button.
    setTimeout (() => {
    if (this.currentUser) {
      this.afService.getFriendRequests(this.profileInfo[0].userID, this.currentUser[0].userID).subscribe((data) => {
        if (data.length > 0) {
          this.requestToggle = true;
        }
      });
      this.afService.getFriendRequestsFrom(this.profileInfo[0].userID, this.currentUser[0].userID)
      .subscribe(data => {
        if (data.length > 0) {
          this.requestToggle = true;
        }
      });
    }

    // Hides buttons if on own profile.
    if (this.profileInfo[0].userID == this.currentUser[0].userID) {
      this.showButtons = false;
    } else {
      this.showButtons = true;
    }
  }, 1000);
  }

}

服务:

import { Injectable } from "@angular/core";
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
import { Router, ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Rx';
import "rxjs/add/operator/map";

@Injectable()
export class AF {
  public currentUserDetails;

  constructor(public af: AngularFireAuth, private database: AngularFireDatabase, private router: Router) {
  }

// Get all currently logged in user details.
getCurrentUserInfo() {
  return new Promise((resolve, reject) => {
    this.af.authState.subscribe(authData => {
      let email = authData.email;
      let array = this.database.list('registeredUsers', {
        query: {
        orderByChild: 'email',
        equalTo: email
      }
    }).subscribe(data => {
      let currentUserDetails = data[0];
      resolve(currentUserDetails);
      });
    });
  });
}

// Get all users details.
getAllAthletes(): Observable<any> {
  return this.database.list('registeredUsers');
}

// Get useer details for the current profile route.
getAthleteProfile(userID) {
  return this.database.list('registeredUsers', {
    query: {
      orderByKey: userID,
      equalTo: userID
    }
  })
}

// Register new user.
registerUser(email, password) {
  return this.af.auth.createUserWithEmailAndPassword(email, password);
}

// Add new user details to database.
addUserEntry(uid, fname, lname, email) {
  return this.database.object('registeredUsers/' + uid).set({
    firstName: fname,
    lastName: lname,
    email: email,
    userID: uid,
    bio: "Your short bio goes here...",
    phone: 5555555555
  });
}

// Add friend request to both parties.
addFriendRequest(profileUID, currentUID, profileFirstName, profileLastName, currentFirstName, currentLastName) {
  return this.database.object('registeredUsers/' + currentUID + '/friends/requests/requestTo/' + profileUID).set({
    requestTo: profileUID,
    firstName: profileFirstName,
    lastName: profileLastName
  }).then(() =>
  this.database.object('registeredUsers/' + profileUID + '/friends/requests/requestFrom/' + currentUID).set({
    requestFrom: currentUID,
    firstName: currentFirstName,
    lastName: currentLastName
  })
)}

/* (TODO): Consolidate lines 81-99.  Replace the paths with variables set in the components.
---*
---*/

// Check if user sent a friend request to user being viewed.
getFriendRequests(profileUID, currentUID) {
  return this.database.list('registeredUsers/' + currentUID + '/friends/requests/requestTo/' + profileUID)
}

// Check if user received a friend request from user being viewed.
getFriendRequestsFrom(profileUID, currentUID) {
  return this.database.list('registeredUsers/' + currentUID + '/friends/requests/requestFrom/' + profileUID)
}

// Get all sent friend requests.
getPendingFriendRequests(currentUID) {
  return this.database.list('registeredUsers/' + currentUID + '/friends/requests/requestTo/');
}

// Get all received friend requests.
getPendingFriendRequestsFrom(currentUID) {
  return this.database.list('registeredUsers/' + currentUID + '/friends/requests/requestFrom/');
}

// Update the user account info.
updateUserEntry(uid, fname, lname, phone, bio) {
  return this.database.object('registeredUsers/' + uid).update({
    firstName: fname,
    lastName: lname,
    phone: phone,
    bio: bio
  });
}

// Login
loginWithEmail(email, password) {
  return this.af.auth.signInWithEmailAndPassword(email, password).then(()=> {
    this.router.navigate(['/dashboard']);
  }).catch(function(error) {
    var errorMessage = error.message;
  })
}

// Logout
logout() {
  this.af.auth.signOut().then(() =>
    this.router.navigate(['/login'])
)}
}

接近最后,我将函数包装在1秒setTimeout函数中,因为需要填充数组currentUser才能使其正常运行。数组总是被填充,但速度不够快,因此该函数永远不会在没有setTimeout的情况下运行。

有没有办法告诉Angular “在填充此数组后运行此函数”

,而不是使用setTimeout

1 个答案:

答案 0 :(得分:2)

首先,在服务中不需要Promise,你只需返回observable:

import 'rxjs/add/operator/mergeMap';



getCurrentUserInfo() {
    return this.af.authState.mergeMap(authData => {
        return this.database.list('registeredUsers', {
            query: {
                orderByChild: 'email',
                equalTo: authData.email
            }
        });
    }).map(data => {
        let currentUserDetails = data[0];
        resolve(currentUserDetails);
    });
}
  

注意:如果你不知道可观察物是如何工作的,你应该看看   一些教程。

之后,您可以在组件中使用它。我们知道,我们需要currentUserprofileInfo bevor我们可以执行您的功能。这意味着,两个可观察者都需要得到补充:

import 'rxjs/add/observable/forkJoin';

Observable.forkJoin(
    this.afService.getAthleteProfile(id),
    this.afService.getCurrentUserInfo()
).subscribe((results) => {
    results[0]; //This is the result of getAthleteProfile
    results[1]; //This is the result of getCurrentUserInfo

    //Now, push the values into the arrays 
    yourFunction(); //and execute your function here
});

注意:不要忘记导入您的Observable操作符:

import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/mergeMap';