我正在使用Angular 4,AngularFire2和Firebase构建应用程序。
我遇到了一个问题。
在我的 app-component.html 中,我有:
<app-person *ngIf="isPerson" [personId]="personId" [treeUniqueName]="treeUniqueName" [treeId]="treeId"></app-person>
在我的 app-component.ts 中,我有这个:
import { Component } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
isTree = false;
treeId;
treeUniqueName = '';
treeDisplayName = '';
isPerson = false;
personId = '';
isLocation = false;
locationId = '';
isEvent = false;
eventId = '';
isDocument = false;
documentId = '';
isSitemap = false;
data = '';
headers = new Headers();
constructor(
protected db: AngularFireDatabase
) {}
ngOnInit() {
let cleanPath = location.pathname.toLowerCase().replace(/\/+$/, '');
//console.info(cleanPath);
cleanPath = cleanPath || '';
if (cleanPath === '/sitemap') {
this.isSitemap = true;
}
let routeSegments = cleanPath.split("/");
//console.info(routeSegments);
if (routeSegments.length >= 3 && routeSegments[1] == 'family')
{
this.treeUniqueName = routeSegments[2].toLowerCase();
let output = this.db.list('/tree', {
query: {
orderByChild: 'unique',
equalTo: this.treeUniqueName
}
}).subscribe(tree => {
this.treeId = tree[0].$key;
this.treeDisplayName = tree[0].display;
console.log(this.treeId);
})
if (routeSegments.length == 3)
{
this.isTree = true;
}
else if (routeSegments.length == 5 && routeSegments[3].toLowerCase() == 'person')
{
this.isPerson = true;
this.personId = routeSegments[4].toLowerCase();
}
else if (routeSegments.length == 5 && routeSegments[3].toLowerCase() == 'location')
{
this.isLocation = true;
this.locationId = routeSegments[4].toLowerCase();
}
else if (routeSegments.length == 5 && routeSegments[3].toLowerCase() == 'event')
{
this.isEvent = true;
this.eventId = routeSegments[4].toLowerCase();
}
else if (routeSegments.length == 5 && routeSegments[3].toLowerCase() == 'document')
{
this.isDocument = true;
this.documentId = routeSegments[4].toLowerCase();
}
}
}
}
如果我检查页面,我看到数据属性正在被正确绑定:
<app-person ng-reflect-tree-id="964f000f-573b-481b-9e43-18bc77" ng-reflect-tree-unique-name="doe" ng-reflect-person-id="b051cb21-6419-4b6f-85b5-d0891bc2a166"><!--bindings={
"ng-reflect-ng-for-of": ""
}--></app-person>
但是在我的 person.component.ts 中我有这个:
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import { Title, Meta } from '@angular/platform-browser';
import { EventPipe } from './event.pipe';
@Component({
selector: 'app-person',
templateUrl: './person.component.html'
})
export class PersonComponent implements OnInit, OnDestroy {
@Input() treeId: string;
@Input() treeUniqueName: string;
@Input() personId: string;
subscriptions: Array<any> = new Array<any>();
people: Array<any> = new Array<any>();
constructor(
private title: Title,
private meta: Meta,
protected db: AngularFireDatabase
){}
ngOnInit() {
console.log(this.treeId); // FOR SOME REASON THIS IS EMPTY
this.subscriptions.push(
this.db.list('/person', {
query: {
queryByChild: 'tree',
equalTo: this.treeId,
limitToLast: 200
}
}).subscribe(people => {
this.people = people;
})
);
}
ngOnDestroy() {
this.subscriptions.forEach(s => s.unsubscribe());
}
}
由于某种原因,this.treeId始终为空。
我猜这与页面生命周期有关?如果是这样,我该如何解决它?
答案 0 :(得分:0)
正确的语法是:
<app-person *ngIf="isPerson" [personId]="personId" [treeUniqueName]="treeUniqueName" [treeId]="treeId"></app-person>
对于@Input值,您不需要{{}}。
对于isPerson,您需要在父组件中设置它,而不是通过@Input在子组件中设置它。
答案 1 :(得分:0)
由于您的treeId仅在异步函数的回调中定义(在您的情况下...订阅结果),子组件除非您告诉它,否则不会等待它。它将在app组件发生后立即实例化。你有一个布尔值来告诉子组件等待“isPerson”,但似乎有许多条件会设置“isPerson”#39;为true,无论treeId是否仍为空字符串。所有这些条件都在订阅部分后同步评估,他们也不会等待。您可以尝试不将treeId初始化为空字符串,只需声明它并保持未定义。
treeId: string;
然后将应用程序组件模板中的ngIf语句更改为
*ngIf="isPerson && treeId"
Vega是正确的,你通常会避免在模板的构造函数中放置任何东西,但在你的情况下,这些东西似乎都不依赖于视图或任何输入,所以你可能很好。这是我认为与你的问题无关的事情,但是你如何得到&#39; location&#39;在没有位置提供商的应用程序组件中?
答案 2 :(得分:0)
我想出了解决这个问题的方法。我将代码移出app.component.ts
的构造函数并进入ngOnInit。这没有效果。
然后我切换了'person.component.ts&#39;的ngOnInit。是一个ngOnChanges。现在,此代码在app.component.ts
代码之后触发 - 这是所需的。
this.treeId
现已正确填充。