我有以下数据结构:
{
"users" : {
"AXLKSD9ASLKDJJ0991" : {
"authType" : "ap1",
"enabled" : true,
"color" : "red"
},
"A778ASDUASDJ8AS8DA" : {
"authType" : "ap1",
"enabled" : true,
"color" : "blue"
},
"ASD88ASD8ASD8HAS8D" : {
"authType" : "ap2",
"enabled" : true,
"color" : "red"
}
}
}
我创建了一个专门用于Firebase的服务,该服务具有以下方法。这成功地将用户返回到我的组件中:
firebase.service.ts:
userList: FirebaseListObservable<any[]>;
getUsersByAuthType(authType: string) {
return this.userList = this.afDb.list('/users', {
preserveSnapshot: true,
query: {
orderByChild: 'authProvider',
equalTo: authType
}
});
}
admin.component.ts:
import { Component, OnInit } from '@angular/core';
import { FirebaseService } from '../services/firebase.service';
@Component({
selector: 'app-administration',
templateUrl: './admin.component.html',
styleUrls: ['./admin.component.css']
})
export class AdministrationComponent implements OnInit {
usersData: any;
constructor(
private firebaseService: FirebaseService
) { }
ngOnInit() {
this.usersData = this.firebaseService.getUsersByAuthType('ap1');
}
}
admin.component.html:
<h2>test 1</h2>
<ul *ngFor="let user of (usersData | async)">
<li>{{ user.enabled }}</li>
</ul>
<br /><br /><br />
<h2>test 2</h2>
{{ usersData | async | json }}
<br /><br /><br />
<h2>test 3</h2>
<ul *ngFor="let user of (usersData | async)">
<li>{{ user.key }}</li>
</ul>
&#34;测试1&#34;没有显示任何东西..
&#34;测试2&#34;显示整个返回的json对象:
{ "authType" : "ap1", "enabled" : true, "color" : "red" }, { "authType" : "ap1", "enabled" : true, "color" : "blue" }
&#34;测试3&#34;向我展示了钥匙。
我尝试过其他一些方法但没有成功。参考文档表明我正在做的事情是好的
https://github.com/angular/angularfire2/blob/master/docs/4-querying-lists.md
想法?
更新
我还在admin.component.html中添加了以下内容:
<br /><br /><br />
<h2>test 4</h2>
<ul *ngFor="let user of (usersData | async)">
<li>{{ (user | json) }}</li>
</ul>
这也在渲染页面中产生了以下输出:
更新#2
总结一些建议......
<ul *ngFor="let user of (usersData | async)">
<li>{{ user[user.key].enabled }}</li>
</ul>
<ul *ngFor="let user of (usersData | async)">
<li>{{ user[user.key]?.enabled }}</li>
</ul>
这些都没有返回任何内容,也没有记录任何错误。
以下是有趣的:
<ul *ngFor="let user of (usersData | async)">
<li>{{ user.val }}</li>
</ul>
这在组件中呈现了以下内容:
更新#3
建议将呼叫映射到我的firebase服务,如下所示:
ngOnInit() {
this.usersData = this.firebaseService.getUsersByAuthType('ap1')
.map(res => res.json());
}
然后按如下所示更新我的组件视图:
<ul *ngFor="let user of (usersData | async)">
<li>{{ user?.enabled }}</li>
</ul>
这导致以下错误:
ERROR TypeError: res.json is not a function
at MapSubscriber.project (administration.component.ts:26)
at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (map.js:77)
at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at SwitchMapSubscriber.webpackJsonp.../../../../rxjs/operator/switchMap.js.SwitchMapSubscriber.notifyNext (switchMap.js:124)
at InnerSubscriber.webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:23)
at InnerSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at Notification.webpackJsonp.../../../../rxjs/Notification.js.Notification.observe (Notification.js:32)
at QueueAction.webpackJsonp.../../../../rxjs/operator/observeOn.js.ObserveOnSubscriber.dispatch (observeOn.js:87)
at QueueAction.webpackJsonp.../../../../rxjs/scheduler/AsyncAction.js.AsyncAction._execute (AsyncAction.js:111)
at QueueAction.webpackJsonp.../../../../rxjs/scheduler/QueueAction.js.QueueAction.execute (QueueAction.js:33)
我还尝试将整个usersData转储出来:
<h3>The whole lot</h3>
{{ usersData }}
渲染:
[object Object]
同样值得分享一下,当我在console.log中返回firebase服务的内容时,它会返回:
[DataSnapshot,DataSnapshot]
如果我展开它,你可以清楚地看到两个数组元素及其键属性,但是子节点不能立即可见但深埋在结构中:
经过一些在线阅读后,似乎我需要创建一个自定义管道进行转换,但我不知道如何去做。我所看到的例子,首先是错误,不能编译,但也不清楚它是如何工作的。
我是否在正确的轨道上?
我仍然坚持为什么&#34;测试4&#34;我完全按照我的期望和需要呈现,我只是无法通过属性名称访问它(例如,启用,authType等)?
更新#4
我已将admin.component.html更新为:
<h3>Test 5</h3>
<ng-container *ngIf="usersData != null && usersData.length !== 0">
<ul *ngFor="let user of usersData">
<li>{{ user?.enabled }}</li>
</ul>
</ng-container>
我已经更新了admin.component.ts ngOnInit,如下所示,并从@ angular / core导入了markForCheck:
ngOnInit() {
this.usersData = this.firebaseService.getUsersByAuthType('ap1')
.map(res => res.json())
.subscribe(result => {
this.usersData = result;
this.ref.markForCheck();
});
}
控制台提供以下见解:
AdminComponent.html:32 ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
at NgForOf.webpackJsonp.../../../common/@angular/common.es5.js.NgForOf.ngOnChanges (common.es5.js:1659)
at checkAndUpdateDirectiveInline (core.es5.js:10831)
at checkAndUpdateNodeInline (core.es5.js:12330)
at checkAndUpdateNode (core.es5.js:12269)
at debugCheckAndUpdateNode (core.es5.js:13130)
at debugCheckDirectivesFn (core.es5.js:13071)
at Object.eval [as updateDirectives] (AdministrationComponent.html:32)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13056)
at checkAndUpdateView (core.es5.js:12236)
at callViewAction (core.es5.js:12601)
core.es5.js:1020 ERROR TypeError: res.json is not a function
at MapSubscriber.project (administration.component.ts:30)
at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (map.js:77)
at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at SwitchMapSubscriber.webpackJsonp.../../../../rxjs/operator/switchMap.js.SwitchMapSubscriber.notifyNext (switchMap.js:124)
at InnerSubscriber.webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:23)
at InnerSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at Notification.webpackJsonp.../../../../rxjs/Notification.js.Notification.observe (Notification.js:32)
at QueueAction.webpackJsonp.../../../../rxjs/operator/observeOn.js.ObserveOnSubscriber.dispatch (observeOn.js:87)
at QueueAction.webpackJsonp.../../../../rxjs/scheduler/AsyncAction.js.AsyncAction._execute (AsyncAction.js:111)
at QueueAction.webpackJsonp.../../../../rxjs/scheduler/QueueAction.js.QueueAction.execute (QueueAction.js:33)
非常感谢任何帮助。
答案 0 :(得分:0)
试试这个:
user[user.key].enabled
OR
问题在于结果的类型。尝试在调用subscribe或“async”之前映射结果:
ngOnInit() {
this.usersData = this.firebaseService.getUsersByAuthType('ap1')
.map(res => res.json());
}
你不需要那个| JSON
你现在可以去:<ul *ngFor="let user of (usersData | async)">
<li>{{ user?.enabled }}</li>
</ul>
使用sync而不是async:
users: any;
constructor(private ref: ChangeDetectorRef) {}
ngOnInit() {
this.usersData = this.firebaseService.getUsersByAuthType('ap1')
.map(res => res.json()).subscribe(result => {
users = result.users;
this.ref.markForCheck();
});
}
<ng-container *ngIf="user != null && user.length !== 0">
<ul *ngFor="let user of user">
<li>{{ user?.enabled }}</li>
</ul>
</ng-container>
您现在可以在订阅中设置调试器,以显示您正在接收的数据类型。实际上,它必须工作。
答案 1 :(得分:0)
所以问题归结为preserveSnapshot选项。
原始firebase.service.ts snippit:
userList: FirebaseListObservable<any[]>;
getUsersByAuthType(authType: string) {
return this.userList = this.afDb.list('/users', {
preserveSnapshot: true,
query: {
orderByChild: 'authProvider',
equalTo: authType
}
});
}
我需要放弃 preserveSnapshot:true 并将其设置为 false 。
admin.component.ts(无变化):
import { Component, OnInit } from '@angular/core';
import { FirebaseService } from '../services/firebase.service';
@Component({
selector: 'app-administration',
templateUrl: './admin.component.html',
styleUrls: ['./admin.component.css']
})
export class AdministrationComponent implements OnInit {
usersData: any;
constructor(
private firebaseService: FirebaseService
) { }
ngOnInit() {
this.usersData = this.firebaseService.getUsersByAuthType('ap1');
}
}
admin.component.html(无更改):
<ul *ngFor="let user of (usersData | async)">
<li>{{ user.enabled }}</li>
</ul>
组件按预期正确呈现。不确定 preserveSnapshot:true 是组件html的问题,但它确实存在。
如果有人知道为什么会这样,我很想知道。