mobx: как наблюдать изменения во вложенных объектах? - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть две модели: MessageModel, который содержит текст сообщения (наблюдаемый), и MessageListModel, который содержит список этих MessageModel объектов (также наблюдаемых).

Я зарегистрировал mobx.autorun() при каждом изменении списка сообщений.

Однако autorun срабатывает при добавлении / удалении сообщений из списка, но не при изменении текста существующих сообщений.

Пример:

My MessageListModel:


import { observable, decorate } from "mobx";
import MessageModel from "./MessageModel";
import * as mobx from "mobx";

class MessageListModel {

  messages = [];

  constructor() {
        mobx.autorun(() => {
          console.log('Autorun triggered!');
          console.log(this.messages.length);
        });
    }

  addMessage(text) {
    this.messages.push(new MessageModel({ messageList: this, text: text }));
  }

  getMessageText(index) {
    return this.messages[index].text;
  }

  setMessageText(index, messageText) {
    this.messages[index].text = messageText;
  }
}

decorate(MessageListModel, {
  messages: observable,  // don't wanna use decorator syntax
})


export default MessageListModel;

my MessageModel:


import { observable, computed, action, decorate } from "mobx";
import {observer} from "mobx-react";

class MessageModel {

  constructor({messageList, text}) {
    this.text = text;
    this.messageList = messageList;
  }

  text = undefined;
}

decorate(MessageModel, {
  text: observable,
})


export default MessageModel;

Попытка запустить это:

const messageList = new MessageListModel();

messageList.addMessage('msg1');   // triggers autorun
messageList.addMessage('msg2');   // triggers autorun

messageList.setMessageText(1, 'other text');  // does not trigger autorun
messageList.setMessageText(0, 'other text');  // does not trigger autorun either


как мне заставить его наблюдать изменения в моих сообщениях, а не в их количестве?

1 Ответ

1 голос
/ 08 февраля 2020

В вашем методе autorun вы только слушаете изменений в length массива сообщений, поэтому единственное, что отслеживается в этой функции autorun, это свойство length массива.

попробуйте изменить autorun на это, чтобы увидеть разницу:

mobx.autorun(() => {
  console.log('Autorun triggered!');
  console.log(this.messages.length);

  this.messages.map((model)=>{
    console.log(model.text)
  })      
});

В приведенном выше примере мы обращаемся к свойству text в model, поэтому каждый раз, когда вы изменяете text в любой модели, будет выполняться autorun.

Таким образом, autorun будет запускаться только при изменении свойств, которые явно отслеживаются (доступ осуществляется внутри функции).

...