2016-10-13 18 views
3

AngularFire2を使用して簡単なチャットアプリケーションを作成しようとしています。ユーザーはFacebookにログインし、プロファイル情報をusers/uidに保存します。ユーザーがチャットを送信するたびに、メッセージとともにUIDが送信されます。現在作業中のユーザーの情報にUIDをマップしようとしています。しかし、メッセージを追加/削除すると、データの一部が点滅し、新しい情報で更新するのではなく、再レンダリングしているように見えます。より具体的には、自分自身ではないすべてのプロファイル情報が更新されます。私はFirebaseから来ているのと同じように私がなぜフラッシュしないのかも分かりません。誰もが点滅を修正する方法の手掛かりを持っていますか?ここでAngular2 ngForネストされたObservable/FirebaseObjectObservableで更新時にデータが点滅する

chat.service.ts

import { Injectable } from '@angular/core'; 
import { AngularFire, FirebaseListObservable } from 'angularfire2'; 
import { Observable } from 'rxjs'; 
import 'rxjs/Rx'; 

@Injectable() 
export class ChatService { 
    chat_list$: Observable<any>; 
    items$: FirebaseListObservable<any>; 
    constructor(public af: AngularFire) { 
    this.items$ = af.database.list('/items', { 
     query: { limitToLast: 15, orderByKey: true} 
    }); 
    this.chat_list$ = this.items$.map(chats => { 
     console.log('chats: ', chats); 
     return chats.map(chat => { 
     if (chat.sender !== af.database.object(`users/${chat.uid}`)) { 
      chat.sender = af.database.object(`users/${chat.uid}`); 
     } 
     return chat; 
     }); 
    }); 
    } 
} 

home.component.ts

import { Component } from '@angular/core'; 
import { AuthService } from '../services/auth.service'; 
import { ChatService } from '../services/chat.service'; 


@Component({ 
    selector: 'app-home', 
    templateUrl: './home.component.html', 
    styleUrls: ['./home.component.scss'] 
}) 
export class HomeComponent { 
    name: string; 
    message: string; 
    constructor(public auth: AuthService, public chat: ChatService) { 
    auth.isLoggingIn = false; 
    } 
    onMessageSend(form){ 
    console.log('form submit: ', form); 
    this.chat.items$.push(form); 
    this.message = ''; 
    } 
    removeChat(chat_key){ 
    this.chat.items$.remove(chat_key); 
    } 
} 

home.component.html

<div class="container m-t-1"> 
<div class="row"> 
    <div class="col-xs-12"> 
    <h1>Quick Chat App</h1> 
    <button class="btn btn-danger pull-right" (click)="auth.signout()">Sign Out</button> 
</div> 
</div> 
<form (ngSubmit)="onMessageSend(sendForm.value)" #sendForm="ngForm"> 
<ul class="m-t-1"> 
    <li *ngFor="let chat of chat.chat_list$ | async"> 
    <img src="{{ (chat.sender | async)?.photo }}" alt="{{ (chat.sender | async)?.name }}'s profile picture"> 
    <span class="message">{{ chat.message }}</span> <span class="tag tag-primary m-l-1">{{ (chat.sender | async)?.name }}</span> 
    <span class="tag tag-danger" (click)="removeChat(chat.$key)">X</span> 
    </li> 
</ul> 
<div class="input-group m-t-1"> 
    <input name="message" [(ngModel)]="message" type="text" class="form-control" placeholder="Enter message..." autocomplete="off" required> 
    <span class="input-group-btn"> 
    <button class="btn btn-primary" type="submit"><i class="fa fa-send-o"></i></button> 
    </span> 
</div> 
<label for="message" class="pull-right posting-as">Posting as {{auth.user.name}}</label> 
<input type="hidden" name="uid" [(ngModel)]="auth.user.uid"> 
</form> 
</div> 

答えて

1

私の最初の答えを簡素化での私の第二の試みは、さらに良いです。それをチェックしてください、私はまだそれが最適化できるかどうかを見ています。

chat.service.ts

import { Injectable } from '@angular/core'; 
import { AngularFire, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2'; 
import { Observable } from 'rxjs'; 
import 'rxjs/Rx'; 

@Injectable() 
export class ChatService { 
    chat_list: Array<any>; 
    chat_list$: Observable<any>; 
    chat_senders$: any = {}; 
    items$: FirebaseListObservable<any>; 
    constructor(public af: AngularFire) { 
    this.items$ = af.database.list('/items', { 
     query: { limitToLast: 15, orderByKey: true} 
    }); 
    this.chat_list$ = this.items$.map(chats => { 
     chats.map(chat => { 
     this.chat_senders$[chat.uid] = af.database.object(`users/${chat.uid}`); 
     this.chat_senders$[chat.uid].subscribe((sender) => { 
      chat.sender = sender; 
     }); 
     return chat; 
     }); 
     return chats; 
    }); 
    } 
} 

home.component.html

<div class="container m-t-1"> 
<div class="row"> 
    <div class="col-xs-12"> 
    <h1>Quick Chat App</h1> 
    <button class="btn btn-danger pull-right" (click)="auth.signout()">Sign Out</button> 
</div> 
</div> 
<form (ngSubmit)="onMessageSend(sendForm.value)" #sendForm="ngForm"> 
<ul class="m-t-1"> 
    <li *ngFor="let chat of chat.chat_list$ | async"> 
    <img src="{{ chat.sender?.photo }}" alt="{{ chat.sender?.name }}'s profile picture"> 
    <span class="message">{{ chat.message }}</span> <span class="tag tag-primary m-l-1">{{ chat.sender?.name }}</span> 
    <span class="tag tag-danger" (click)="removeChat(chat.$key)">X</span> 
    </li> 
</ul> 
<div class="input-group m-t-1"> 
    <input name="message" [(ngModel)]="message" type="text" class="form-control" placeholder="Enter message..." autocomplete="off" required> 
    <span class="input-group-btn"> 
    <button class="btn btn-primary" type="submit"><i class="fa fa-send-o"></i></button> 
    </span> 
</div> 
<label for="message" class="pull-right posting-as">Posting as {{auth.user.name}}</label> 
<input type="hidden" name="uid" [(ngModel)]="auth.user.uid"> 
</form> 
</div> 
0

ですFirebaseと私のコンテンツとの間の余分なレイヤーを含むソリューションの私の最初の試み。他の誰かがより良い解決策を持っていますか?

chat.service.ts

import { Injectable } from '@angular/core'; 
import { AngularFire, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2'; 
import { Observable } from 'rxjs'; 
import 'rxjs/Rx'; 

@Injectable() 
export class ChatService { 
    chat_list: Array<any>; 
    chat_list$: Observable<any>; 
    chat_senders$: any = {}; 
    items$: FirebaseListObservable<any>; 
    constructor(public af: AngularFire) { 
    this.items$ = af.database.list('/items', { 
     query: { limitToLast: 15, orderByKey: true} 
    }); 
    this.chat_list$ = this.items$.map(chats => { 
     chats.forEach(chat => { 
     this.chat_senders$[chat.uid] = af.database.object(`users/${chat.uid}`); 
     }); 
     return chats; 
    }); 
    this.chat_list$.subscribe(chat_list => { 
     this.chat_list = chat_list.map(chat => { 
     this.chat_senders$[chat.uid].subscribe((sender) => { 
      chat.sender = sender; 
     }); 
     return chat; 
     }); 
     console.log(this.chat_list); 
    }); 
    } 
} 

home.component.html

<div class="container m-t-1"> 
<div class="row"> 
    <div class="col-xs-12"> 
    <h1>Quick Chat App</h1> 
    <button class="btn btn-danger pull-right" (click)="auth.signout()">Sign Out</button> 
</div> 
</div> 
<form (ngSubmit)="onMessageSend(sendForm.value)" #sendForm="ngForm"> 
<ul class="m-t-1"> 
    <li *ngFor="let chat of chat.chat_list"> 
    <img src="{{ (chat.sender)?.photo }}" alt="{{ (chat.sender)?.name }}'s profile picture"> 
    <span class="message">{{ chat.message }}</span> <span class="tag tag-primary m-l-1">{{ (chat.sender)?.name }}</span> 
    <span class="tag tag-danger" (click)="removeChat(chat.$key)">X</span> 
    </li> 
</ul> 
<div class="input-group m-t-1"> 
    <input name="message" [(ngModel)]="message" type="text" class="form-control" placeholder="Enter message..." autocomplete="off" required> 
    <span class="input-group-btn"> 
    <button class="btn btn-primary" type="submit"><i class="fa fa-send-o"></i></button> 
    </span> 
</div> 
<label for="message" class="pull-right posting-as">Posting as {{auth.user.name}}</label> 
<input type="hidden" name="uid" [(ngModel)]="auth.user.uid"> 
</form> 
</div> 
関連する問題