Как обновить существующий объект внутри наблюдаемого массива в Angular? - PullRequest
0 голосов
/ 09 апреля 2020

В моем приложении Ioni c 5 / Angular я пытаюсь обновить объект Conversation в массиве ниже Conversation:

private _conversations = new BehaviorSubject<Conversation[]>([
    new Conversation(
      'conversation1',
      'user3',
      'user1',
      [
        new Message('message1', 'Test message', 'user3', new Date(2018, 0O5, 0O5, 17, 23, 42, 11)),
        new Message('message2', 'Another message', 'user1', new Date(2018, 0O6, 0O5, 17, 23, 42, 11))
      ]),
    new Conversation(
      'conversation2',
      'user4',
      'user2',
      [
        new Message('message3', 'my  message', 'user4', new Date(2018, 0O7, 0O7, 17, 23, 42, 11)),
        new Message('message4', 'more messages', 'user2', new Date(2018, 0O7, 0O7, 17, 23, 42, 11)),
      ])
  ]);

Вот Conversation & Message моделей, которые я использую:

export class Conversation {
    constructor(
        public id: string,
        public userId: string,
        public mechanicId: string,
        public messages: Message[]
    ) { }
}

export class Message {
    constructor(
        public id: string,
        public text: string,
        public userId: string,
        public timestamp: Date
    ) { }
}

Я могу добавить в массив следующие методы:

addConversation(mechanicId: string, message: string) {
    const newConversation = new Conversation(
      Math.random().toString(),
      this.authService.userId,
      mechanicId,
      [this.createMessage(message)]
    );
    return this.conversations.pipe(
      take(1),
      delay(1000),
      tap(conversations => {
        this._conversations.next(conversations.concat(newConversation));
      }));
  }

  private createMessage(message: string): Message {
    return {
      id: Math.random().toString(),
      text: message,
      userId: this.authService.userId,
      timestamp: new Date(Date.now())
    };
  }

Но я не могу обновить Conversation (т. Е. Добавить новый объект Message к существующему объекту Conversation).

Вот моя последняя попытка:

addToConversation(id: string, mechanicId: string, message: string) {
    const conversation = this.getConversation(id);
    if (conversation) {
      conversation.messages.push(
        this.createMessage(message)
      );
    }
  }

Однако это не работает, так как я получите следующее сообщение об ошибке conversation.messages.push:

Свойство 'messages' не существует для типа Observable <{id: string, userId: string, mechanicId: string, messages: Message []; }>

Также вот getConversation():

getConversation(id: string) {
    return this.conversations.pipe(
      take(1),
      map(conversations => {
        return { ...conversations.find(conversation => conversation.id === id) };
      }));
  }

get conversations() {
    return this._conversations.asObservable();
  }

Ответы [ 3 ]

1 голос
/ 09 апреля 2020

Если вам нужен доступ к текущему значению предмета Поведение, вы можете использовать метод getValue(). Возвращает текущее значение, удерживаемое субъектом поведения. Использование pipe, map и take(1) выглядит излишним для меня. Попробуйте следующее

getConversation(id: string) {
  return this._conversations.getValue().find(conversation => conversation.id === id);
}

addMessageToConversation(conversationId: string, message: Message) {
  this.getConverstation().messages.push(message);
}

Затем вызовите функцию addMessageToConversation() в любом месте кода

addToConversation(id: string, mechanicId: string, message: string) {
  this.addMessageToConversation(id, this.createMessage(message));
  .
  .
}
0 голосов
/ 09 апреля 2020

Я думаю, что это решит вашу проблему, изменит модель Message и изменит createMessage функцию

    class Message {
    public id: string
    public text: string
    public userId: string
    public timestamp: Date
    constructor(
        options: any = {}
    ) {
        this.id = options.id || '';
        this.text = options.text || '';
        this.userId = options.userId || '';
        this.timestamp = options.timestamp || null; // null or new Date()
    }
}

private createMessage(message: string): Message {
    return new Message({
      id: Math.random().toString(),
      text: message,
      userId: this.authService.userId,
      timestamp: new Date(Date.now())
    });
  }

, если нет, дайте мне знать

0 голосов
/ 09 апреля 2020

В потоке данных вы не можете изменить объект. Вы должны создать (испустить) новые данные. Здесь, в вашем случае, вы создаете / pu sh новые данные, используя

observer.next(conversation) и takeLast(1) вместо take(1) takeLast всегда получит последнее значение.

sample:

addToConversation(id: string, mechanicId: string, message: string) {
  const conversation = this.getConversation(id);
  if (conversation) {
    conversation.messages.push(
      this.createMessage(message)
    );
  this._conversations.next(conversation)
  }

}

Получить последний:

getConversation(id: string) {
    return this.conversations.pipe(
      takeLast(1),
      map(conversations => {
        return { ...conversations.find(conversation => conversation.id === id) };
      }));
  }

Весь код:

export class Conversation {
  constructor(
    public id: string,
    public userId: string,
    public mechanicId: string,
    public messages: Message[]
  ) {}
}

export class Message {
  constructor(
    public id: string,
    public text: string,
    public userId: string,
    public timestamp: Date
  ) {}
}
class X {
  private messages = [
    new Conversation("conversation1", "user3", "user1", [
      new Message(
        "message1",
        "Test message",
        "user3",
        new Date(2018, 0o5, 0o5, 17, 23, 42, 11)
      ),
      new Message(
        "message2",
        "Another message",
        "user1",
        new Date(2018, 0o6, 0o5, 17, 23, 42, 11)
      ),
    ]),
    new Conversation("conversation2", "user4", "user2", [
      new Message(
        "message3",
        "my  message",
        "user4",
        new Date(2018, 0o7, 0o7, 17, 23, 42, 11)
      ),
      new Message(
        "message4",
        "more messages",
        "user2",
        new Date(2018, 0o7, 0o7, 17, 23, 42, 11)
      ),
    ]),
  ];
  private _conversations = new BehaviorSubject<Conversation[]>(this.messages);
  addToConversation(id: string, mechanicId: string, message: string) {
    const conversation = this.messages.find((conversation) => conversation.id === id)
    if (conversation) {
      conversation.messages.push(this.createMessage(message));
    }
    this._conversations.next(conversation)
  }
  addConversation(mechanicId: string, message: string) {
    const newConversation = new Conversation(
      Math.random().toString(),
      this.authService.userId,
      mechanicId,
      [this.createMessage(message)]
    );
    return this.conversations.pipe(
      takeLast(1),
      delay(1000),
      tap((conversations) => {
        this._conversations.next(conversations.concat(newConversation));
      })
    );
  }
  getConversation(id: string) {
    return this.conversations.pipe(
      take(1),
      map((conversations) => {
        return {
          ...conversations.find((conversation) => conversation.id === id),
        };
      })
    );
  }

  get conversations() {
    return this._conversations.asObservable();
  }
  private createMessage(message: string): Message {
    return {
      id: Math.random().toString(),
      text: message,
      userId: this.authService.userId,
      timestamp: new Date(Date.now()),
    };
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...