我正在尝试进行简单的导入,但我遇到了大量stack trace问题。
我尝试到处寻找与此相关的问题,但对我来说,堆栈跟踪并没有提供太多信息。
编辑:我尝试将其设置为一个不从Firebase获取的变量,它运行正常。我想现在的问题是如何处理来自Firebase的这些信息,以便它在准备就绪时加载。
以下是相关文件:
main.ts:
import { bootstrap } from '@angular/platform-browser-dynamic';
import {AppComponent} from './app.component';
import { HTTP_PROVIDERS } from '@angular/http';
bootstrap(AppComponent, [HTTP_PROVIDERS]);
player.services.ts:
import { Injectable } from '@angular/core';
import {Player} from "../classes/player";
@Injectable()
export class PlayerService {
player: Player;
getPlayer()
{
return Promise.resolve(this.player);
}
createPlayer(uid: string, name: string, firebaseRef: Firebase)
{
this.player = {
'uid': uid,
'name': name,
'level': 1,
'maxHealth': 100,
'health': 100,
'maxEnergy': 50,
'energy': 50,
'fun': 1,
'skill': 1,
'knowledge': 1
}
firebaseRef.child('players').child(uid).set(this.player);
}
setPlayer(player: Player)
{
this.player = player;
}
}
app.component.ts
import { Component, OnInit } from '@angular/core'
import { PlayerDetailComponent } from './components/player-detail.component';
import {PlayerService} from "./services/player.service";
import {FirebaseEventPipe} from "./firebasepipe";
import {Player} from "./classes/player";
@Component({
selector: "my-app",
templateUrl: 'app/views/app.component.html',
directives: [PlayerDetailComponent],
providers: [PlayerService],
pipes: [FirebaseEventPipe]
})
export class AppComponent implements OnInit{
title = "title";
authData: any;
private firebaseUrl: string;
private firebaseRef: Firebase;
private loggedIn = false;
player: Player;
constructor(private playerService: PlayerService) {
this.firebaseUrl = "https://!.firebaseio.com/";
this.firebaseRef = new Firebase(this.firebaseUrl);
this.firebaseRef.onAuth((user) => {
if (user) {
this.authData = user;
this.loggedIn = true;
}
});
}
getPlayer() {
this.firebaseRef.once("value", (dataSnapshot) => {
if (dataSnapshot.child('players').child(this.authData.uid).exists()) {
this.firebaseRef.child('players').child(this.authData.uid).once("value", (data) => {
this.player = data.val();
this.playerService.setPlayer(this.player);
console.log(this.player);
});
} else {
this.playerService.createPlayer(this.authData.uid, this.getName(this.authData), this.firebaseRef);
this.playerService.getPlayer().then(player => this.player);
console.log(this.player);
}
});
}
ngOnInit() {
this.getPlayer();
}
authWithGithub() {
this.firebaseRef.authWithOAuthPopup("github", (error) =>
{
if (error) {
console.log(error);
}
});
}
authWithGoogle() {
this.firebaseRef.authWithOAuthPopup("google",(error) =>
{
if (error) {
console.log(error);
}
});
}
getName(authData: any) {
switch (authData.provider) {
case 'github':
return authData.github.displayName;
case 'google':
return authData.google.displayName;
}
}
}
玩家detail.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { Player } from '../classes/player';
@Component({
selector: "player-details",
templateUrl: "app/views/player-detail.component.html",
styleUrls: ['app/style/player-detail.component.css'],
})
export class PlayerDetailComponent implements OnInit{
@Input() player: Player;
ngOnInit() { console.log(this.player)}
}
app.component.html
<nav class="navbar navbar-default">
<div class="container">
<ul class="nav navbar-nav">
<li class="navbar-link"><a href="#">Home</a></li>
</ul>
</div>
</nav>
<div class="jumbotron" [hidden]="loggedIn">
<div class="container">
<h1>Angular Attack Project</h1>
<p>This is a project for the <a href="https://www.angularattack.com/">Angular Attack 2016</a> hackathon. This is a small project where set goals
in order to gain experience as a player and person. In order to begin, please register with on of the following services</p>
<button class="btn btn-social btn-github" (click)="authWithGithub()"><span class="fa fa-github"></span>Sign Up With Github </button>
<button class="btn btn-social btn-google" (click)="authWithGoogle()"><span class="fa fa-google"></span>Sign Up With Github </button>
</div>
</div>
<player-details [player]="player" [hidden]="!loggedIn"></player-details>
玩家detail.component.html
<div id="player" class="panel panel-default">
<div id="player-stats" class="panel-body">
<img id="player-image" class="img-responsive" src="../app/assets/images/boy.png"/>
<div class="health-bars">
<div class="health-bar">HEALTH:<br/><progress value="{{ player.health }}" max="{{ player.maxHealth }}"></progress></div>
<div class="energy-bar">ENERGY:<br/><progress value="{{ player.energy }}" max="{{ player.maxEnergy }}"></progress></div>
<div class="player-attributes"><span class="fa fa-futbol-o player-attr fun">: {{ player.fun }} </span><span class="fa fa-cubes player-attr skill">: {{ player.skill }}</span> <span class="fa fa-graduation-cap player-attr knowledge">: {{ player.knowledge }}</span></div>
</div>
</div>
</div>
答案 0 :(得分:1)
在您的服务中,您不必返回承诺。你可以使用一个getter
private player: Player;
get CurrentPlayer()
{
return this.player;
}
然后在你的组件中:
getPlayer() {
this.firebaseRef.once("value", (dataSnapshot) => {
if (dataSnapshot.child('players').child(this.authData.uid).exists()) {
this.firebaseRef.child('players').child(this.authData.uid).once("value", (data) => {
this.playerService.setPlayer(this.player);
console.log(this.player);
});
} else {
this.playerService.createPlayer(this.authData.uid, this.getName(this.authData), this.firebaseRef);
console.log(this.player);
}
});
ngOnInit() {
this.player = this.playerService.CurrentPlayer();
this.getPlayer();
}
如果先设置参考,则应自动更新。您还可以在DOM中抛出* ngIf播放器详细信息组件定义,并且只有在播放器对象未定义时才显示它。
修改强> 刚看到其他人在我之前发布了关于* ngIf的信息,所以如果这是解决方案,请标记他们的。
答案 1 :(得分:0)
加载PlayerDetailComponent
时,播放器变量未定义,因此没有播放器这样的对象。
要解决此问题,OnChanges
可以像这样实现:
import { Component, Input, OnChanges, SimpleChange } from '@angular/core';
import { Player } from '../classes/player';
import {HealthBarComponent} from "./health-bar.component";
import {ChecklistComponent} from "./checklist.component";
@Component({
selector: "player-details",
templateUrl: "app/views/player-detail.component.html",
styleUrls: ['app/style/player-detail.component.css'],
directives: [HealthBarComponent, ChecklistComponent],
})
export class PlayerDetailComponent implements OnChanges{
@Input()
player: Player;
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
}
}
然后我们可以在模板中添加*nfIf="player"
以确保在加载元素之前播放器对象不为空。