Angular + Firebase:如何使用列表属性存储/检索对象?

时间:2017-06-04 05:48:16

标签: angular firebase angularfire2

chatroom.service.ts:

...
export class Message {
  author: string;
  body: string;
}

export class Chatroom {
  title: string;
  messages: Message[];  // <-- seems to be the problem
}

@Injectable()
export class ChatroomService {
  ...
  getChatroom = (chatroomId: string): FirebaseObjectObservable<Chatroom> =>
    this.db.object('/chatrooms/' + chatroomId);
  ...

chatroom.component.ts:

...
export class ChatroomComponent implements OnInit {
  chatroom: Chatroom;

  private sub: any;

  ngOnInit() {
    this.sub = this.route.params
      .subscribe(params => {
        this.sub = this.chatroomService.getChatroom(params['chatroomId'])
          .subscribe(chatroom => this.chatroom = chatroom);
      });
  }
  ...

chatroom.component.html

<div *ngIf="chatroom">
  <p *ngFor="let message of chatroom.messages">{{message.author}}: {{message.body}}</p>
</div>

错误:

Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

问题是Chatroom对象的“message”属性被Firebase视为对象,而我希望它被视为ngFor-iterable列表。关于如何使这项工作的任何建议?

编辑:以下是Firebase数据结构:

{
  "chatrooms" : {
    "chatroom_342768235" : {
      "title" : "a chatroom",
      "messages" : {
        "message_3252253" : {
          "author" : "Joe",
          "body" : "test message"
        },
        "message_2653837" : {
          "author" : "Kim",
          "body" : "another message"
        }
      }
    },
    "chatroom_426482763" : {
      "title" : "another chatroom",
      "messages" : {
        "message_1243525" : {
          "author" : "Tom",
          "body" : "blah blah"
        }
      }
    }
  }
}

2 个答案:

答案 0 :(得分:0)

我认为因为你听DB(有了订阅)你得到一个Observable列表,而* ngFor不能使用那种列表。您应该尝试在要迭代的Observable列表之后添加| async管道。像这样:

<p *ngFor="let message of chatroom.messages | async">{{message.author}}: {{message.body}}</p>

答案 1 :(得分:0)

如果可能,请在messages类的Chatroom属性中添加setter / getter方法。

messages属性声明为typed array

export class Chatroom {
  title: string;
  private _messages : {[key: string]: Message[]}; 

  public set messages(value: {[key: string]: Message[]}) {
        this._messages = {};
        for (let msg in value) {
               this._messages[msg] = value[msg];
        }
  }

  public get messages(): {[key: string]: Message[]} {
    return this._messages;
  }

}

使用这种方法messages属性是一个带字符串索引的正确数组,现在应该是可迭代的。使用类型化数组的唯一原因是您可以访问邮件message_2653837message_3252253的名称。