2016-10-13 3 views
3

AngularFire2를 사용하여 간단한 채팅 앱을 만들려고합니다. 사용자는 페이스 북에 로그인하고 프로필 정보를 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>