2012-04-22 18 views
24

Realmente no obtengo la función de ember.js 'reopenClass. Pensé que agregaba código adicional al prototipo del Objeto, por lo que todas las instancias de ese Objeto obtendrían la funcionalidad que se agregó de una manera no estática. No hace esto sin embargo. Parece que solo agrega código que se puede ejecutar estáticamente. Por ejemplo. Tengo este código:Ember.js ¿cómo funciona reopenClass?

Logger = Ember.Object.extend({ 
    log: function(thing) { 
    console.log(thing + ' wassup'); 
    } 
}); 

var logger = Logger.create(); 
logger.log("1, yo") 

logger.reopen({ 
    log: function(name) { 
     console.log(name + 'ghurt') 
    } 
}); 
logger.log("2, yo") 

Logger.reopenClass({ 
    log: function(name) { 
     console.log(name + 'fresh') 
    } 
}); 
logger.log("3, yo") 
Logger.log("4, yo") 

Genera esto:

1, yo wassup 
2, yoghurt 
3, yoghurt 
4, yofresh 

Lo que esperaba era esto:

1, yo wassup 
2, yoghurt 
3, yofresh 
4, undefined (I think) 

Así que mi pregunta es: ¿Qué reopenClass hacer y cuándo hacerlo lo uso ¿eso?

Respuesta

44

En general, reopen añade métodos y propiedades para casos mientras que reopenClass añade métodos y propiedades para clases.

Las pruebas correspondientes son ember-runtime/tests/system/object/reopen_test.js y packages/ember-runtime/tests/system/object/reopenClass_test.js.

He actualizado el código y añadí algunos comentarios, ver http://jsfiddle.net/pangratz666/yWKBF/:

Logger = Ember.Object.extend({ 
    log: function(thing) { 
     console.log(thing + ' wassup'); 
    } 
}); 

var logger1 = Logger.create(); 
var logger2 = Logger.create(); 

// instances of Logger have a 'wassup' method 
try { Logger.log("1, yo"); } catch (e) {} // Object (subclass of Ember.Object) has no method 'log' 
logger1.log("1, yo"); // 1, yo wassup 
logger2.log("1, yo"); // 1, yo wassup 

console.log('----'); 

// overwrite log of concrete logger instance logger1 
logger1.reopen({ 
    log: function(name) { 
     console.log(name + ' ghurt'); 
    } 
}); 

try { Logger.log("1, yo"); } catch (e) {} // Object (subclass of Ember.Object) has no method 'log' 
logger1.log("2, yo"); // 2, yo ghurt 
logger2.log("2, yo"); // 2, yo wassup 

console.log('----'); 

// classes of Logger have a 'fresh' method 
Logger.reopenClass({ 
    log: function(name) { 
     console.log(name + ' fresh'); 
    } 
}); 

Logger.log("3, yo"); // 3, yo fresh 
logger1.log("3, yo"); // 3, yo ghurt 
logger2.log("3, yo"); // 3, yo wassup 

console.log('----'); 

// new* instances of Logger have from now on a 'dawg' method 
// * this will likely change in the future so already existing instances will reopened too 
Logger.reopen({ 
    log: function(name) { 
     console.log(name + ' dawg'); 
    } 
}); 

Logger.log("4, yo"); // 4, yo fresh 
logger1.log("4, yo"); // 4, yo ghurt 
logger2.log("4, yo"); // 4, yo wassup 
Logger.create().log("4, yo"); // 4, yo dawg 

console.log('----'); 

+9

Ok, por lo Si obtengo esto r ight logger.reopen() solo agrega el código a la instancia del registrador, Logger.reopen() agrega código para cada instancia nueva que se creará (las instancias existentes no se modificarán) y Logger.reopenClass() agrega código que es estático para la clase Logger (no se puede invocar desde instancias, solo estáticamente). ¿Correcto? – koenpeters

+0

Sí, eso es correcto. – pangratz

+2

Ok. Gracias por arrojar luz. Me costó entender esto (como en: No lo obtuve) de la documentación en http://emberjs.com/documentation/. – koenpeters

0

reopen cambios prototipo y por lo tanto cambia instancias de una clase

reopenClass cambia el constructor sí mismo y así cambia la clase creando las propiedades y funciones estáticas que son solo están disponibles en la clase pero no en ninguna instancia de la clase.

Tenga en cuenta que los cambios introducidos por reopen sólo tienen efecto después de llamar .create()

Ejemplos de código basado en el doc:

http://emberjs.com/api/classes/Ember.Application.html#method_reopen

MyObject = Ember.Object.extend({ 
    name: 'an object' 
}); 

o = MyObject.create(); 
o.get('name'); // 'an object' 

MyObject.reopen({ 
    say: function(msg){ 
    console.log(msg); 
    } 
}) 

try{ 
    o.say("hey"); 
} catch(e) { 
    console.log(e); // o.say is not a function (...yet) 
} 
o2 = MyObject.create(); 
o2.say("hello"); // logs "hello" 

o.say("goodbye"); // logs "goodbye" 

http://emberjs.com/api/classes/Ember.Application.html#method_reopenClass

MyObject = Ember.Object.extend({ 
    name: 'an object' 
}); 

MyObject.reopenClass({ 
    canBuild: false 
}); 

MyObject.canBuild; // false 
o = MyObject.create(); 
o.canBuild; // undefined