【问题标题】:push string to observable<chatmessages[ ]>将字符串推送到 observable<chatmessages[ ]>
【发布时间】:2020-12-11 10:39:30
【问题描述】:

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

我的 chat-message.model.ts

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

这是我已经尝试过的:

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

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

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

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

【问题讨论】:

    标签: angular typescript observable behaviorsubject


    【解决方案1】:

    您不能将某些内容推送到可观察对象,因为它是一个流。您所描述的可以通过许多不同的方法来完成。例如,您可以创建 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();
     }
     
    }
    

    【讨论】:

    • 非常感谢您的解释!
    猜你喜欢
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 2020-02-25
    相关资源
    最近更新 更多