2016-03-03 2 views
2

Я считаю, что решение моей проблемы относительно просто. Я просто этого не вижу.Загрузить объект с логикой

У меня есть объект:

function MyObject(){ 
    this.attr = "anything"; 
} 

MyObject.prototype.doSomething = function(){ 
    // logic 
} 

я создаю объект с помощью new MyObject(). Я использую его, и когда я хочу отказаться от того, что я делаю, я просто храню его в базе данных (mongodb). В Монго он хранится таким образом:

{ "attr" : "anything" } 

Когда я загрузить объект из базы данных у меня только простой литерал объекта без какой-либо логики. Методы отсутствуют. Я могу понять, почему;), но я не знаю, как добавить логику к объекту буквального снова ...

Вопрос

Как я могу украсить полученный объект с его оригинальной логикой снова? Так что это выглядит, как это снова:

{  
    "attr" : "anything", 
    "doSomething": doSomething() 
} 
  • Как сделать это просто?
  • Есть ли другой подход к этому (за исключением хранения методов и всей иерархии прототипов с ним)?
+0

json не может выполнять функции. почему у вас нет модели (MyObject) в качестве модуля, и при инициализации вы можете передать ей json из базы данных, чтобы установить ее состояние? – eltonkamami

+0

@antoniskamamis Не могли бы вы предоставить пример кода? – zatziky

ответ

3

Вы можете использовать Object.create для создания объекта из прототипа без вызова конструктора, а затем использовать Object.assign присвоить свойство объекта, который вы извлекаемые, на вновь созданный объект:

var fullObject = Object.assign(Object.create(MyObject.prototype), retrievedObject); 

Пример:

function MyObject(){ 
 
    this.attr = "anything"; 
 
} 
 

 
MyObject.prototype.doSomething = function(){ 
 
    document.body.innerHTML = this.attr; 
 
} 
 

 
// Plain object retrieved from database 
 
var retrievedObject = {  
 
    "attr" : "foobar" 
 
}; 
 

 
// Object with proper prototype and properties 
 
var myObject = Object.assign(Object.create(MyObject.prototype), retrievedObject); 
 

 
myObject.doSomething();

+0

его главная задача - хранить весь конструктор и его прототип в db, который нельзя сделать только с json – eltonkamami

+0

или может быть выполнен, но он должен содержать некоторую логику. – eltonkamami

+0

@antoniskamamis Прежде всего, это можно было бы сделать с помощью JSON, все может быть сохранено в JSON, вам просто нужен способ его сериализации в строку, а затем снова неэтериализовать его. Во-вторых, это явно не его главная забота, на самом деле он никогда не упоминал о необходимости хранить функции в db и явно упоминал о желании украсить объект после извлечения его из db. – Paulpro

4

Создайте функцию загрузки, чтобы загрузить все свойства объекта, который вы вернетесь в свой собственный объект.

Вы можете получить доступ к именам объектов ваших объектов в качестве индекса ассоциативного массива.

так myobj.attr такое же, как myobj['attr'].

Это помогает динамически вставлять данные в свой объект в то время сохраняя полный контроль над данными (мой личный фаворит) :-)

Вы можете добавить некоторые дополнительные проверки для предотвращения избыточных данных или сделать некоторые дополнительные вещи, все, что вы хотите , Например, изменение временных меток.

function MyObject(data){ 
    if(typeof data !== 'undefined') { 
    this.load(data); 
    } 
    else { 
     this.attr = "anything"; 
    } 
} 

MyObject.prototype.doSomething = function(){ 
    // logic 
} 
MyObject.prototype.load = function(data) { 
    for(var key in data) { 
     if(data.hasOwnProperty(key)) { 
     this[key] = data[key]; 
     // Just sample validation check. wahtever you want. 
     if(key == 'timestamp') { 
      if(this[key] < new Date().getTime()-4000) { 
        this[key] = new Date().getTime(); 
      } 
     } 
     } 
    } 
} 
+0

Спасибо. От просмотра кода он работает. Я реализовал решение @Paulpro. – zatziky

0

Продолжение @ paulpro Ответит, который я должен был изменить немного этот кусок кода Object.create(MyObject.prototype). Поскольку я использовал унаследованный объект таким образом, он не создавал должным образом private членов. Я просто заменил Object.create(MyObject.prototype) на new MyObject(). Вот и все.

UPDATE 5/3/2016

Самый безопасный способ заключается в использовании lodash's assing.

var objectWithLogic = _.assign(new MyObject(), data); 
Смежные вопросы