Как сказать postMessage структурированный клон игнорировать свойства? - PullRequest
0 голосов
/ 31 января 2019

Я работаю над проектом, в котором мне нужно создать объект в iframe, а затем отправить указанный объект в родительское окно.

Проблема в том, что postMessage не удается, так как объект не может бытьклонируется (DataCloneError), поскольку имеет свойство function (callback).

Что еще более усложняет это, так это циклическая связь, при которой списки кнопок содержат кнопки, а каждая кнопка имеет ссылку на свой родительский список.

Если бы при этом использовалось JSON.stringify вместо структурированного клонирования, можно переопределить toJSON на кнопке и избежать отправки callback и заменить list на listId, чтобы избежать циклической эталонной ситуации.Существует ли эквивалент toJSON для структурного клонирования, который позволил бы игнорировать callback при сохранении циклических отношений или другого решения?

Это грубая суть ситуации с воспроизводимой ошибкой:

class ButtonList {
    constructor() {
        this.buttons = [];
    }

    addButton(button) {
        if (!this.buttons.includes(button)) {
            this.buttons.push(button);
            button.setList(this);
        }
        return this;
    }
}

class Button {
    setList(list) {
        if (!list) return this;
        if (this.list !== list) {
            this.list = list;
            list.addButton(this);
        }
        return this;
    }

    setCallback(callback) {
        this.callback = callback;
        return this;
    }

    getCallback() {
        return this.callback;
    }

    runCallback() {
        if (!this.callback) return this;
        this.callback();
        return this;
    }
}

const list = new ButtonList();
const button = new Button().setList(list).setCallback(() => console.log('Hello'));
window.postMessage(list, '*');

// DataCloneError: The object could not be cloned.

Родительскому окну не нужно знать обратный вызов, но нужно знать любые другие свойства.

1 Ответ

0 голосов
/ 31 января 2019

Создайте новый объект с перезаписанными свойствами с Object.assign и отправьте его через postMessage.

const foo = {
  bar: 'bar',
  list: { bla: 'bla' },
  baz: function() {
    console.log('baz')
  }
}

const serializable = Object.assign({}, foo, { 
  list: 3,
  baz: undefined 
})

console.log(serializable)
...