将字符串推送到 observable<chatmessages[ ]>

push string to observable<chatmessages[ ]>

我正在尝试创建一个聊天应用程序,并希望用户发送的消息显示在聊天室中(在我的项目中称为提要),就像显示所有其他已经存在的消息一样 (我有一个getMessages()

如何将用户键入的消息推送到我的 chatMessage[]

这是我的message.Service.ts

@Injectable({
  providedIn: 'root'
})
export class MessageService {
  user: User;
  userName: Observable<string>;

  chatMessage: ChatMessage;
  chatMessages$: Observable<ChatMessage[]>;

    constructor(
    private http: HttpClient,
    private accountService: AccountService) {
      this.user = this.accountService.userValue;
     }
 

sendMessage(msg: string){
  const timestamp = this.getTimeStamp()

this.chatMessages$ = this.getMessages();
this.chatMessages$.push({ //having trouble here
  msg_content: msg,       //Property 'push' does not exist on type 'Observable<ChatMessage[]>'.
  timeSent: timestamp,
  userName: this.userName,
  email: this.user.email });

var formdata = new FormData();
formdata.append("sender_email", this.user.email);
formdata.append("sender_key", this.user.api_key);
formdata.append("msg_content", msg);
this.http.post("http://11.123.456.78:5000/messages/send_message", formdata )
  .subscribe(response => console.log(response), error => console.log('oops', error));
}

getMessages(){
  let params = new HttpParams().set("sender_email", "this.user.email").set("sender_key", "someapikey"); //Create new HttpParams 
  var url = "http://11.123.456.78:5000/messages/get_all_messages";
   return this.chatMessages$ = this.http.get<ChatMessage[]>(url, { params: params});
 }
}

我的feed.component.ts

export class FeedComponent implements OnInit {
  chatMessages$: Observable<ChatMessage[]>;
  messages;
  messageObjects: string[] = [];

  constructor(private chat: MessageService) { 
  }
 
  ngOnInit() {
  this.messages = this.chat.getMessages().subscribe((allmessagesdata => { this.messages = allmessagesdata
  for (let messageObject of this.messages){
    this.messageObjects.push(messageObject.msg_content)
  };
 }));
 this.chatMessages$ = this.chat.getMessages();
 
  }
  
  ngOnchanges(){
    this.chat.getMessages().subscribe((allmessagesdata => { this.messages = allmessagesdata,  console.log(this.messages)}))
    
  }
}

我的feed.html

<div *ngFor="let message of ( chatMessages$ | async )" >
<app-message [chatMessage]="message"> </app-message>    
</div>

我的聊天-message.model.ts

export class ChatMessage {
    $id?: string;
    email?: string;
    userName?: string;
    msg_content?: string;
    timeSent?: Date = new Date();
}

这是我已经尝试过的方法:

我尝试设置 private subject = new Subject<string>(); 然后在我的 sendMessage() 函数中说 this.subject.next(msg) 然后我创建了

getMessage():Observable<string> {
  return this.subject.asObservable();
}

并在我的供稿中订阅了它,但这只允许一个消息值。

我对可观察对象和主题的了解有限,我似乎还不能完全掌握这个概念,但我知道我必须为此目的使用它们,因此非常感谢任何帮助

您不能将某些内容推送到可观察对象,因为它是一个流。您所描述的可以通过许多不同的方法来完成。例如,您可以创建 ChatMessage[] 的 BehaviorSubject,它将存储“最近”消息,然后 chatMessages$ 应该是后端消息和最近消息的组合。

我的提议(我想到的第一个,在这里操场上做了一些概念测试:https://stackblitz.com/edit/rxjs-evjqhb

@Injectable({
  providedIn: 'root'
})
export class MessageService implements OnInit, OnDestroy{
  user: User;
  userName: Observable<string>;

  private _sendMessage = new Subject<ChatMessage>();
  private _destroy = new Subject<ChatMessage>();
  private _recentMessages = new BehaviorSubject<ChatMessage[]>([]);
  
  
  chatMessage: ChatMessage;
  existedChatMessages$: Observable<ChatMessage[]>;
  recentChatMessages$: Observable<ChatMessage[]>;
  chatMessages$: Observable<ChatMessage[]>;

    constructor(
    private http: HttpClient,
    private accountService: AccountService) {
      this.user = this.accountService.userValue;
     }
 

sendMessage(msg: string){
  const timestamp = this.getTimeStamp()


const message = {
  msg_content: msg,
  timeSent: timestamp,
  userName: this.userName,
  email: this.user.email };

  
  this._sendMessage.next(message);

// you can move this to a tap() operator in the _sendMessage subject
var formdata = new FormData();
formdata.append("sender_email", this.user.email);
formdata.append("sender_key", this.user.api_key);
formdata.append("msg_content", msg);
this.http.post("http://11.123.456.78:5000/messages/send_message", formdata )
  .subscribe(response => console.log(response), error => console.log('oops', error));
}

getMessages(){
  let params = new HttpParams().set("sender_email", "this.user.email").set("sender_key", "someapikey"); //Create new HttpParams 
  var url = "http://11.123.456.78:5000/messages/get_all_messages";
   return this.chatMessages$ = this.http.get<ChatMessage[]>(url, { params: params});
 }
 
 ngOnInit(){
    chatMessages$ = this.existedChatMessages$.pipe(
        switchMap(existed=> 
            this.recentChatMessages$].pipe(
                map(recent)=>[...(existed||[]), ...recent]
            )
        )
    ); // combine streams of backend & recent messages
    
    this.existedChatMessages$ = this.getMessages();
    this.recentChatMessages$ = this._recentMessages.asObservable();
    this._recentMessages.pipe(
        switchMap(recentMessages => this._sendMessage.pipe(
                map(message=> [...recentMessages, message]))
            )
        ),
        tap(x=> this._recentMessages.next(x)),
        takeUntil(this._destroy)
    ).subscribe(); // creating subscription for sendMessage subject to update recentMessages collection
    
    
 }
 
 ngOnDestroy(){
    this._destroy.next();
    this._destroy.complete();
 }
 
}