2014-10-25 2 views
0

Используя NodeJS, я пытаюсь отслеживать изменения атрибутов Model независимо от того, какой тип они могут быть. С помощью Object.defineProperty сеттеры обычно работают отлично, но для объектов и массивов, если свойство объекта установлено, я не могу отслеживать сделанные изменения.Object defineProperty setter для свойств

Я понимаю, что сеттер не является самим объектом, но есть ли способ заставить его функционировать так, как будто это так?

Например, могу ли я получить приведенный ниже код для запуска сеттера, когда установлено свойство «setter»?

var model = {}; 
model.attributes = {}; 

Object.defineProperty(model, 'options', { 
    get: function() { 
     return this.attributes.options; 
    }, 
    set: function(value) { 
     console.log('changed options from:', this.attributes.options, 'to', value); 
     this.attributes.options = value; 
    } 
}); 

model.options = {}; 
model.options = { a: 50 }; // triggers setter 
model.options.b = 60;  // doesn't trigger setter, how can I get it to do so? 
+0

короче: нет, вы можете» t подписывать неизвестные свойства, включая под-свойства с ODP. загляните в объект Object.observe() - тип – dandavis

+0

@ dandavis Ah, bummer. Похоже, что Node поддерживает только Object.observe в последних версиях (т.е. нестабильных), поэтому я могу просто изучить некоторые другие подходы. Спасибо за помощь! –

+0

Прокси-сервер Harmony может помочь вам – Vinz243

ответ

3

Если вы используете transpiler ES6, который поддерживает прокси-серверы, вы можете решить эту проблему, как так:

var handler = { 
    defineProperty (target, key, descriptor) { 
    console.log('changed options from:', target[key], 'to', descriptor.value); 
    if(typeof descriptor.value === 'object'){ 
     descriptor.value = new Proxy(descriptor.value,handler); 
    } 
    Object.defineProperty(target, key, descriptor); 
    return true; 
    } 
} 

var target = {} 
var proxy = new Proxy(target, handler) 

proxy.foo = 'bar2'  // changed from undefined to bar2 
proxy.foo = 'bar'   // changed from bar2 to bar 
proxy.options = { a: 50 } // changed from undefined to Object { a: 50 } 
proxy.options.a = 15  // changed from 50 to 15 
proxy.options.b = 60  // changed from undefined to 60 

Вдохновленный this статьи

+0

Прокси могут это сделать, но эта реализация не устраняет основную проблему: обнаружение, когда вложенные свойства определены/установлены. Вы можете видеть, что я имею в виду здесь: https://jsfiddle.net/rosszurowski/ef0h67qq/1/ Возможно, это можно решить с помощью свойства 'set' обработчика? –

+0

Да, моя первоначальная попытка была немного неряшливой, проверьте мою отредактированную версию. В зависимости от того, как вы хотите его использовать, вы можете увеличить его немного больше. – Karamell

+0

Ха-ха, это непростой способ сделать это, но он работает. Благодаря! –

Смежные вопросы